Binding, что это такое и для чего он нужен

Во первых Binding это привязка данных, это просто и думаю все это прекрасно понимают и ни для кого это не станет откровением. Но не все понимают что с чем привязывается и зачем это надо, ну так давайте попробуем в этом разобраться. Первая и самая главная полезность которую мы получаем при использовании Binding'ов это разделение понятий отображения и логики, то есть грубо говоря мы имеем некую «морду» которую мы показываем пользователю и логику данных которая спрятана за этой «мордой». Так вот, начнем с простого примера, как все начинают .

Код окна:

<Window x:Class="WpfBinding.SampleBinding"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="SampleBinding" Height="300" Width="300" Loaded="Window_Loaded">
   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="*"/>
           <RowDefinition Height="Auto"/>
       </Grid.RowDefinitions>
       <TextBox Name="helloBox" Text="{Binding TextData}"/>
       <Button Name="helloBtn" Grid.Row="4" Width="100" Content="Hello" Click="helloBtn_Click" HorizontalAlignment="Right"/>
   </Grid>
</Window>

и соответственно код нашей логики данных, то бишь SampleBinding.cs файл:

using System.Windows;
 
namespace WpfBinding
{
    /// <summary>
    /// Interaction logic for SampleBinding.xaml
    /// </summary>
    public partial class SampleBinding 
    {
        public SampleBinding()
        {
            InitializeComponent();
        }
 
        public string TextData { get; set; }
 
        private void helloBtn_Click(object sender, RoutedEventArgs e)
        {
            TextData = "Hello";
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            TextData = "Click Hello button";
        }
    }
}

что нам надо, при старте программы загрузить в helloBox строку «Click Hello button» а по нажатию кнопки поменять текст на «Hello», вроде бы все просто, но после запуска программы мы видим что ничего не работает. Почему скажите вы, ведь у нас есть строка Text=»{Binding TextData}» которая должна была обеспечить нам привязку, а потому что просто привязка ничего не значит, ведь мы не указали окну откуда брать данные, привязка есть но с чем не сказано. Мы должны дать нашему окну DataContext к данным которого мы будем привязывать поля нашей формы. DataContext у нас есть, и даже более того судя по строчке Window x:Class=«WpfBinding.SampleBinding» он уже связан с нашим окном, но все-же чтобы завершить привязку немного модифицируем наш код следующим образом.

<Window x:Class="WpfBinding.SampleBinding"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="SampleBinding" Height="300" Width="300" Loaded="Window_Loaded" Name="sampleWindow">
   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="*"/>
           <RowDefinition Height="Auto"/>
       </Grid.RowDefinitions>
       <TextBox Name="helloBox" Text="{Binding ElementName=sampleWindow, Path=TextData}"/>
       <Button Name="helloBtn" Grid.Row="4" Width="100" Content="Hello" Click="helloBtn_Click" HorizontalAlignment="Right"/>
   </Grid>
</Window>

Рассмотрим что изменилось в коде окна. А изменилось то что мы дали имя sampleWindow классу нашего окна и сказали текстовому полю что брать данные надо из элемента с именем sampleWindow по пути TextData, по сути задав ему этим самым DataContext. Но и этого пока не достаточно потому как при инициализации окна когда после создания элементов инициализируются привязки в TextData не заданно значение и мы привязываемся к пустому полю. Так как же быть, как сообщить окну, или даже не окну, а текстовому полю что данные в нашем классе логики изменились. Для этого нам понадобиться тот волшебный интерфейс про который я не раз вспоминал отвечая на вопросы по привязке данных в топиках нашего форума и который так никто и не хочет видеть в упор, речь идет о INotifyPropertyChanged из System.ComponentModel. Что он нам дает, а дает он нам единственное событие которое посылает окну PropertyChangedEventArgs извещая о том что поменялось поле обнови данные. И вот как будет выглядеть код SampleBinding.cs после модификации

using System.ComponentModel;
using System.Windows;
 
namespace WpfBinding
{
    /// <summary>
    /// Interaction logic for SampleBinding.xaml
    /// </summary>
    public partial class SampleBinding : INotifyPropertyChanged
    {
        public SampleBinding()
        {
            InitializeComponent();
        }
 
        private string textData;
        public string TextData
        {
            get { return textData; }
            get
            {
                textData = value;
                OnPropertyChanged("TextData");
            }
        }
 
        private void helloBtn_Click(object sender, RoutedEventArgs e)
        {
            TextData = "Hello";
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            TextData = "Click Hello button";
        }
 
        #region Implementation of INotifyPropertyChanged
 
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}

Рассмотрим что что мы имеем. В результате реализации INotifyPropertyChanged как я говорил раньше мы получаем событие public event PropertyChangedEventHandler PropertyChanged предающее окну сообщение с именем поля класса данных в котором произошли изменения данных благодаря чему окно может обновить свое отображение. Так вот получается что не так уж много надо для успешного применения привязки данных, а именно: окно с элементами которые знают откуда и как брать данные и логика умеющая своевременно сообщить о том что данные изменились…

Продолжение следует…

 
dotnet/wpf_binding.txt · Последние изменения: 2011/01/29 14:25 От Spawn.NET
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki