اشتراکها
آموزش SignalR (بخش دوم)
اشتراکها
دوره آموزش SignalR به زبان فارسی
در این مقاله مفاهیم مختلفی را در ارتباط با DataBinding بررسی خواهیم کرد:
• One Way Binding بخش اول
• INPC بخش اول
• Tow Way Binding بخش اول
• List Binding بخش دوم
• Element Binding بخش دوم
• Data Conversion بخش دوم
در ابتدا مفهوم انقیاد دادهها یا همان DataBinding را مرور میکنیم. به فرآیند مرتبط سازی منابع اطلاعاتی به کنترلها در برنامهها یا به بیان امروزیتر، به Viewها و نمایش اطلاعات در آنها، انقیاد (Databinding) گویند.
One Way Data Binding (انقیاد یک طرفه)
در این حالت اطلاعات را صرفا در یک View و یا یک کنترل نمایش میدهیم و تغییر اطلاعات در View، تاثیری بر روی منبع اطلاعاتی نخواهد داشت.
مثال: یک پروژهی WPF ساده را ایجاد و سپس کلاس Employee را با خصوصیات زیر، تعریف میکنیم:
public class Employee { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee { Name = "Mani", Title = "CEO" }; return emp; } }
در بخش markup فایل MainWindow.xaml کدهای زیر را ایجاد میکنیم:
<Grid> <StackPanel Name="Display"> <StackPanel Orientation="Horizontal"> <TextBlock>First Name :</TextBlock> <TextBlock Margin="5,0,0,0" Text="{Binding Name}"/> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock>Title :</TextBlock> <TextBlock Margin="5,0,0,0" Text="{Binding Title}"></TextBlock> </StackPanel> </StackPanel> </Grid>
برای تکمیل و انجام عملیات Binding کافی است خصوصیت DataContext را با استفاده از متد استاتیک تعریف شدهی در کلاس Employee پر کنیم.
public MainWindow() { InitializeComponent(); DataContext = Employee.GetEmployee(); }
INPC یا INotifyPropertyChanged Interface
پس از بایند کردن اطلاعات به View مورد نظر، ممکن است منبع داده در طول زمان استفاده تغییر کند. از این رو لازم است که این تغییرات، به View اعمال شوند. بدین منظور میبایست ابتدا Interface ، INotifyPropertyChanged را برای کلاس Employee پیاده سازی کنیم:
public class Employee :INotifyPropertyChanged { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee { Name = "Mani", Title = "CEO" }; return emp; } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
پس از پیاده سازی Interface، خصوصیات کلاس Employee نبایستی بصورت AutoProperty باشند. پس پیاده سازی خصوصیات را با تعریف فیلدهای مورد نیاز تغییر میدهیم.
علت تغییر پیاده سازی، لزوم فراخوانی رویداد dOnPropertyChange در بلاک Set خصوصیات کلاس Employee میباشد:
private string _name; private string _title; public string Name { get { return _name; } set { _name = value; OnPropertyChanged(); } } public string Title { get { return _title; } set { _title = value; OnPropertyChanged(); } }
در ادامه ، در بخش CodeBehind در سازنده کلاس کدهای زیر را جایگزین کدهای قبلی می کنیم :
private Employee emp; public MainWindow() { InitializeComponent(); emp = new Employee() { Name = "Mani", Title = "CEO" }; DataContext = emp; }
<StackPanel Orientation="Horizontal"> <Button Click="btnClick" Width="70" Height="30" Content="Change"/> </StackPanel>
در بخش CodeBehind، رویداد Click را به شکل زیر پیاده سازی میکنیم:
private void btnClick(object sender, RoutedEventArgs e) { emp.Name = "Amir"; emp.Title = "Manager"; }
در برنامهی فوق، در ابتدا View با اطلاعات ارسالی در بخش سازنده، پر میشود و با کلیک بر روی دکمه، منبع داده بهروز شده (در اینجا شیء emp) و بهصورت اتوماتیک View ما بهروز خواهد شد.
Tow Way Data binding (انقیاد دو طرفه)
در این حالت از Data binding، با تغییر View، تغییرات بر روی منبع داده نیز اعمال میشوند.
ابتدا بخش markup مثال فوق را با اضافه کردن ویژگی Mode در کنار ویژگی Binding به شکل زیر تغییر میدهیم:
<Grid> <StackPanel Name="Display" > <StackPanel Orientation="Horizontal"> <TextBlock Margin="5,0,0,0">Name :</TextBlock> <TextBox Margin="5,0,0,0" Text="{Binding Name, Mode=TwoWay}"/> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Margin="5,0,0,0">Title :</TextBlock> <TextBox Margin="5,0,0,0" Text="{Binding Title,Mode=TwoWay}"/> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Margin="5,0,0,0">Name :</TextBlock> <TextBlock Margin="5,0,0,0" Text="{Binding Name}"/> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Margin="5,0,0,0">Title :</TextBlock> <TextBlock Margin="5,0,0,0" Text="{Binding Title}"/> </StackPanel> </StackPanel> </Grid>
اگر ویژگی Mode نوشته نشود بصورت پیش فرض بهصورت OneWay تعبیر میشود. حالت قبل. همچنین در کد بالا دو Textbox در صفحه قرار داده شدهاند تا با تغییر محتوای آن بتوانیم تاثیر عملیات دوطرفهی انقیاد را بر روی Textblockهای بعدی مشاهده کنیم.
پس از اجرای برنامه (بخش CodeBehind نیازی به اصلاح ندارد) مقداری جدید در Textbox موجود در صفحه تایپ کنید. کافی است Focus از روی کنترلی که محتوای آن را تغییر دادهاید، عوض شود، بلافاصله Textblock متناظر با آن، با محتوای جدیدی که در منبع داده اعمال شده است بهروز میشود.