מדריך WPF

מדריך WPF – שימוש ב Data Binding: שימוש ב IValueConverter

‏ • Sela

ישנם פעמים בהם נרצה לעשות Binding בין תכונת יעד ותכונת מקור מטיפוסים שונים. לדוגמא, נרצה לעשות תוכנית שבה סימון CheckBox מעלימה כפתור  ואילו הורדת הסימון מציגה אותו. לשם כך יש לבצע קישור בין התכונות Visibility של הכפתור מטיפוס Visibility לבין תכונת IsChecked של ה CheckBox מטיפוס Boolean.

בדוגמא הבאה אנו מנסים לבצע סנכרון שכזה:

<Window x:Class="ValueConverterDemo.MainWindow"
       >="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       >:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="MainWindow"
       Height="350"
       Width="525">
  <StackPanel>
    <Button Content="button"
           Visibility="{Binding ElementName=checkbox, Path=IsChecked}" />
    <CheckBox x:Name="checkbox"
             Content="hide button?" />
  </StackPanel
>
</
Window
>

הרצה של דוגמא זו תדווח על שגיאה "שקטה" במהלך ביצוע ה Binding (תופיע הודעה בחלון ה Debug Output), הבעיה היא שהטיפוסים שונים ולכן לא ברור כיצד לעשות את הסנכרון.

כדי לבצע את ההמרה בין הטיפוסים יש להגדיר מחלקה חדשה המממשת את הממשק IValueConverter. מחלקה זו תאפשר לנו להוסיף לוגיקה משלנו בעת ביצוע ה Binding. הפונקציה המרכזית שיש לממשק זה נקראת Convert. פונקציה זו נקראת כאשר מתבצע Binding ממקור כלשהוא ליעד כלשהוא. פונקציה זו מקבלת מספר פרמטרים כאשר החשוב ביניהם נקרא Value מטיפוס objecy והוא הערך המקורי שיש להמיר. הערך המוחזר מהפונקציה Convert הוא הערך לאחר שעבר המרה.

במקרה שלנו נרצה להמיר את הערך המתקבל מ Boolean לערך מטיפוס Visibility. נעשה זאת ע"י הוספת מחלקה חדשה שתממש IValueConverter באופן הבא:

using System;
using System.Globalization;
using System.Windows;
using
System.Windows.Data;

namespace
ValueConverterDemo
{
 
public class NotBooleanToVisibilityConverter : IValueConverter
  {
   
public object
Convert(
     
object
value,
     
Type
targetType,
     
object
parameter,
     
CultureInfo
culture)
    {
     
bool boolValue = (bool
)value;
     
if
(boolValue)
      {
       
return Visibility
.Collapsed;
      }
     
else
      {
       
return Visibility
.Visible;
      }
    }

   
public object
ConvertBack(
     
object
value,
     
Type
targetType,
     
object
parameter,
     
CultureInfo
culture)
    {
     
throw new NotImplementedException();
    }
  }
}

 

הפונקציה השנייה שיש לממש בממשק IValueConverter היא הפונקציה ConvertBack שעובד באותה צורה, רק שהיא ממירה מערך היעד לערך מקור ולכן צריכה לעשות את הפעולה ההפוכה למה שהתבצע ב Convert. פונקציה זו רלוונטית רק כאשר מבצעים Binding בעל Mode מטיפוס TwoWay או OneWayToSource. בשאר המקרים ניתן לוותר על מימוש פונקציה זו.

כעת לאחר שיצרנו את המימוש שלנו ל IValueConverter נרצה להשתמש בו.

ראשית יש לבצע מיפוי של .NET namespace ל XML namespace באופן הבא:

>:local="clr-namespace:ValueConverterDemo"

 

וכעת ניצור מופע של המחלקה שלנו ב Resources של החלון:

<Window.Resources>
  <local:NotBooleanToVisibilityConverter
 
  
x:Key
="notBooleanToVisibilityConverter" />
</
Window.Resources
>

 

נותר רק להוסיף את הפרמטר Converter ל Binding שהגדרנו מקודם:

  <StackPanel>
    <Button Content="button"
           Visibility="{Binding ElementName=checkbox,
 
                               
Path=IsChecked,
 
                               
Converter={StaticResource notBooleanToVisibilityConverter}}" />
    <CheckBox x:Name="checkbox"
             Content="hide button?" />
  </StackPanel
>

 

הקוד המלא של התוכנית מופיע להלן. מומלץ להריץ בעצמכם ולהתנסות בדוגמא:

<Window x:Class="ValueConverterDemo.MainWindow"
       >="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       >:x="http://schemas.microsoft.com/winfx/2006/xaml"
       >:local="clr-namespace:ValueConverterDemo"
       Title="MainWindow"
       Height="350"
       Width="525">
  <Window.Resources>
    <local:NotBooleanToVisibilityConverter
 
    
x:Key="notBooleanToVisibilityConverter" />
  </Window.Resources>
  <StackPanel>
    <Button Content="button"
           Visibility="{Binding ElementName=checkbox,
 
                               
Path=IsChecked,
 
                               
Converter={StaticResource notBooleanToVisibilityConverter}}" />
    <CheckBox x:Name="checkbox"
             Content="hide button?" />
  </StackPanel
>
</
Window
>

תגיות: , , , ,

arikp

אריק פוזננסקי הוא יועץ בכיר ומרצה בסלע. הוא השלים שני תארי B.Sc. במתמטיקה ומדעי המחשב בהצטיינות יתרה בטכניון. לאריק ידע נרחב בטכנולוגיות מיקרוסופט, כולל .NET עם C#, WPF, Silverlight, WinForms, Interop, COM/ATL, C++ Win32 ו reverse engineering.

תגובות בפייסבוק