Привязки данных в WPF

см. подробнее "WPF 4 unleashed", Adam Nathan

Рассмотрим контрол:
<TextBlock x:Name="currentFolder" DockPanel.Dock="Top" Background="AliceBlue" FontSize="16" />
Для того, чтобы обновлять содержимое этого контрола после того, как будет выбран элемент соответствующего списка можно определить специальный метод:
void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    currentFolder.Text = (treeView.SelectedItem as TreeViewItem).Header.ToString();
    Refresh();
}

Эту же задачу можно решить с помощью привязок(binding):
public MainWindow()
{
    InitializeComponent();
    Binding binding = new Binding();
    // устанавливаем объект-источник
    binding.Source = treeView;
    // выбираем путь к свойству приемника
    binding.Path = new PropertyPath("SelectedItem.Header");
    // устанавливаем приемника
    currentFolder.SetBinding(TextBlock.TextProperty, binding);
}
Много кода? Позже мы покажем, как привязки облегчают разработку.
Устанавливать привязку можно и с помощью статичного метода:
BindingOperations.SetBinding(currentFolder, TextBlock.TextProperty, binding);
Удалить конкретную привязку можно так:
BindingOperations.ClearBinding(currentFolder, TextBlock.TextProperty);
Удалить все привязки к объекту:
BindingOperations.ClearAllBindings(currentFolder);
Не делайте так!

Правильный способ - описывать привязки в XAML коде. Например, так:
<TextBlock x:Name="currentFolder" DockPanel.Dock="Top" 
Text="{Binding ElementName=treeView, Path=SelectedItem.Header}" 
Background="AliceBlue" FontSize="16" />
Поле Path указывает путь к связанному свойству объекта
Поле пути можно использовать и по умолчанию:
<TextBlock x:Name="currentFolder" DockPanel.Dock="Top" 
Text="{Binding SelectedItem.Header, ElementName=treeView}" 
Background="AliceBlue" FontSize="16" />

Для того, чтобы описать источника, как объект, идентичный приемнику, можно указать связанный источник:
{Binding RelativeSource={RelativeSource Self}}

Источником можно указывать и объекты приложения:
<Label x:Name="numItemsLabel"
Content="{Binding Source={StaticResource photos}, Path=Count}"
DockPanel.Dock="Bottom"/>
Однако, для того, чтобы данные источника и приемника были синхронизированы, необходимо:
  • определить event ИмяСвойстваChanged.
  • либо реализовать интерфейс System.ComponentModel.INotifyPropertyChanged и определить содержащий в интерфейсе PropertyChanged (предпочтительнее)
  • либо использовать класс ObservableCollection
public class Photos : ObservableCollection<Photo>

Отобразить коллекцию в контроле ListBox можно так:
<ListBox x:Name="pictureBox" DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource photos}}" …>
…
</ListBox>

Для того, чтобы не описывать одинаковые источники в каждом Binding, в WPF предусмотрен т.н. контекст данных (data context). Например, укажем общий DataContext для Label и ListBox:
<StackPanel DataContext="{StaticResource photos}">
<Label x:Name="numItemsLabel"
Content="{Binding Path=Count}" …/>
…
<ListBox x:Name="pictureBox" DisplayMemberPath="Name"
ItemsSource="{Binding}" …>
…
</ListBox></StackPanel>

<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute" Executed="HelpExecuted"/>
</Window.CommandBindings>

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button MinWidth="75" Margin="10" Command="Help" Content=
“{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/>
<Button MinWidth="75" Margin="10">OK</Button>
</StackPanel>

Last edited Feb 27, 2014 at 10:37 AM by basph, version 19

Comments

No comments yet.