Классы Windows Presentation Foundation System.Object DispatcherObject ApplicationDependencyObject Visual UIElement FrameworkElement Page Shape TextBlock Control ContentControl Frame Window NavigationWindow ButtonBase Button RepeatButton ToggleButton CheckBoxRadioButton RangeBase Slider ProgressBar TextBoxBase TextBox RichTextBox ItemsControl MenuBase MenuContextMenu HeaderedItemsControl MenuItemToolbar TreeViewItem Selector TabControl ListBox ListView ComboBox TreeView ToolBarTray Panel GridCanvas ContentElement FrameworkContentElement FrameworkTemplateStyle NavigationService
Привязка к коллекциям В классе ItemsControl определено свойство ItemsSource, которое используется для привязки коллекции элементов к элементам управления ListBox, ListView или TreeView: Источником данных для элементов управления ItemsControl может быть любая коллекция, реализующая интерфейс IEnumerable. Свойство ItemsSource по умолчанию поддерживает привязку OneWay. Чтобы при вставке и удалении элементов в коллекции автоматически обновлялся элемент управления, в коллекции должен быть реализован интерфейс INotifyCollectionChanged, В WPF определена обобщенная коллекция ObservableCollection с реализацией интерфейса INotifyCollectionChanged. Обновление данных в целевом элементе ItemsControl будет происходить только в случае, когда каждый объект в коллекции, который поддерживает свойства связывания, также реализует интерфейс INotifyPropertyChanged. Когда свойству ItemsSource присвоено значение, коллекция Items становится доступной только для чтения. Когда ItemsSource присваивается значение null, восстанавливается использование коллекции Items. public IEnumerable ItemsSource { get; set; }
Привязка к коллекции в коде. Пример В примере выполняется привязка к коллекциям ObservableCollection и List, которые находятся в объекте data типа Data_3 и доступны через определенные в классе Data_3 свойства DataFromObservableCollection и DataFromList. В привязке к элементу управления listBox_obs для всех свойств привязки используются значения по умолчанию. Привязка к элементу управления listBox_lst выполнена с помощью объекта Binding, что дает возможность настроить свойства привязки. public partial class Window1 : Window { Data_3 data = new Data_3(); private void Window_Loaded(object sender, RoutedEventArgs e) { data.AddDefaults(); listBox_obs.ItemsSource = data.DataFromObservableCollection; listBox_obs.IsSynchronizedWithCurrentItem = true; // для привязки к // выбранному элементу списка Binding bd = new Binding(); bd.Source = data; bd.Path = new PropertyPath("DataFromList"); bd.Mode = BindingMode.TwoWay; listBox_lst.SetBinding(ListBox.ItemsSourceProperty, bd); listBox_lst.IsSynchronizedWithCurrentItem = true; } […code…] }
Привязка к коллекции в разметке. Пример В примере в ресурсах главного окна создаются объекты типа Data_3 с ключом key_data и типа DTimeConverter с ключом key_converter. <ListBox ItemsSource="{Binding Source={StaticResource key_data},Path=DataFromList}" IsSynchronizedWithCurrentItem="True"/> <Window x:Class="Wpf_Binding_ItemsControl.Window1" xmlns=" xmlns:x=" xmlns:zz="clr-namespace:Custom_Data" xmlns:yy="clr-namespace:Wpf_Binding_ItemsControl" Title="Window1" Height="499" Width="630" Loaded="Window_Loaded"> […code…] Для элемента управления ListBox выполняется привязка к свойству DataFromList объекта, который находится в ресурсах и имеет ключ key_data.
Привязка к коллекции в разметке. Пример(продолжение) В примере коллекция из объекта типа Data_3, определенного в ресурсах с ключом key_data, устанавливается как контекст данных в элементе Grid и затем используется в привязках к элементам управления, содержащих значения свойств текущего элемента коллекции. <TextBox Name="textBox_date" Text="{Binding Date, Converter={StaticResource key_converter}}" Height="21" Margin="10,85,10,10 /> <Grid Grid.RowSpan="3" Grid.Column="2" DataContext="{Binding Source={StaticResource key_data}, Path=DataFromObservableCollection}"> <TextBox Text="{Binding Source={StaticResource key_data}, Path=DataFromList/Text}" Grid.Column="2" Height="23" Width="88" Margin="10,0,10,10" VerticalAlignment="Bottom" HorizontalAlignment="Left" /> Можно явно указать в привязке текущий элемент коллекции : В привязках к элементам управления не указан источник данных, поэтому как источник используется контекст данных ближайшего родительского элемента, для которого определен контекст данных.
Представления коллекций WPF выполняет привязку к коллекции только через представление коллекции – объект класса, реализующего интерфейс ICollectionView, созданный явно или по умолчанию. Представление коллекции поддерживает понятие текущего элемента, сортировки, фильтрации и группировки элементов коллекции. Если в исходной коллекции реализован интерфейс INotifyCollectionChanged, изменения, инициированные событием CollectionChanged, передаются представлениям. Представления не изменяют исходные коллекции. Каждая исходная коллекция может иметь несколько связанных с ней представлений, что дает возможность отображать одни и те же данные различными способами. В случае, когда в качестве источника в привязке используется коллекция (а не ее представление), WPF выполняет привязку к представлению коллекции по умолчанию.
Классы представления коллекций Object DispatcherObject CollectionView ItemCollection BindingListCollectionView ListCollectionView DependencyObject CollectionViewSource WPF создает представление по умолчанию для каждой коллекции, которая используется в качестве источника привязки. Ссылку на представление по умолчанию возвращает статический метод класса CollectionViewSource: Для коллекций, которые реализуют только IЕnumerable, представлением по умолчанию является внутренний класс на основе CollectionView. Для коллекций, которые реализуют IList, представление по умолчанию имеет тип ListCollectionView. Для коллекций, реализующих IBindingListView или IBindingList представлением по умолчанию является BindingListCollectionView. Класс CollectionViewSource является XAML представлением класса CollectionView и используется в привязке XAML. public static ICollectionView GetDefaultView( Object source );
Интерфейс ICollectionView Интерфейс реализуется классом CollectionView. Интерфейс включает более 20 свойств и методов и три события. Свойства и методы интерфейса поддерживают текущую позицию в коллекции, сортировку, фильтрацию и группировку элементов коллекции. public interface class ICollectionView : IEnumerable, INotifyCollectionChanged Object CurrentItem { get; } Текущий элемент в представлении. int CurrentPosition { get; } Номер текущего элемента в представлении. bool MoveCurrentTo( Object item ); bool MoveCurrentToPosition( int position ); bool MoveCurrentToNext(); …….. Перемещение указателя на текущий элемент. bool Contains( Object item ); Проверяет, принадлежит ли элемент представлению коллекции. bool IsCurrentAfterLast { get; } bool IsCurrentBeforeFirst { get; } Проверяет позицию текущего элемента. IEnumerable SourceCollection { get; } Ссылка на базовую коллекцию.
Представление коллекции CollectionViewSource. Привязка в коде. Пример В примере создается представление для коллекции ObservableCollection, которая находится в объекте data_rc типа Data_4 и доступна через определенное в классе Data_4 свойство DataFromObservableCollection. Для представления используется тип CollectionViewSource. К представлению применяется фильтр, который включает в представление только те элементы исходной коллекции, у которых первый символ в свойстве Text – это A. Условие фильтрации реализуется с помощью обработчика FilterByFirstSymbol события Filter, определенного в классе CollectionViewSource. private void button_filter_first_symbol_Click(object sender, RoutedEventArgs e) { CollectionViewSource view_1 = new CollectionViewSource(); view_1.Source = data_rc.DataFromObservableCollection; view_1.Filter += new FilterEventHandler(FilterByFirstSymbol); listBox_view_code.ItemsSource = view_1.View; } void FilterByFirstSymbol(object source, FilterEventArgs args) { DataItem_3 curr = args.Item as DataItem_3; if (curr != null) { if (curr.Text[0] == 'A') args.Accepted = true; else args.Accepted = false; }
Представление коллекции ListCollectionView. Привязка в коде. Пример В примере для представления коллекции используется тип ListCollectionView. К представлению применяется фильтр, который включает в представление только те элементы исходной коллекции, у которых значение свойства DoubleValue меньше 5. Условие фильтрации реализуется с помощью метода обратного вызова FilterByDoubleValue, который передается представлению через свойство Filter класса ListCollectionView. private void button_filter_dbl_Click(object sender, RoutedEventArgs e) { ListCollectionView list_CollectionView = new ListCollectionView(data_rc.DataFromObservableCollection); list_CollectionView.Filter = new Predicate (FilterByDoubleValue); listBox_view_code.ItemsSource = list_CollectionView; } bool FilterByDoubleValue(object item) { DataItem_3 curr = item as DataItem_3; if (curr != null) { if (curr.DoubleValue < 5) return true; } return false; }
Создание представления коллекции в XAML. Пример В примере в разметке в ресурсах создается объект пользовательского типа Data_4 с ключом key_data. В ресурсах создается представление CollectionViewSource для коллекции, которая доступна через свойство DataFromObservableCollection класса Data_4. В представлении определяется фильтр с помощью метода FilterByDate_1. <Window x:Class="Wpf_Binding_CollectionView.Window1" xmlns=" xmlns:x=" xmlns:zz="clr-namespace:Custom_Data" xmlns:yy="clr-namespace:Wpf_Binding_CollectionView" Title="Window1" Height="496" Width="702" Loaded="Window_Loaded"> <CollectionViewSource Source= "{ Binding Source={StaticResource key_data}, Path=DataFromObservableCollection}" x:Key="key_view_1" Filter="FilterByDate_1"/> […code…] Представление CollectionViewSource с ключом key_view_1 используется в привязке к элементу управления ListBox. <ListBox Grid.Column="1" Margin="10,30,10,8" Name="listBox_view_xaml_1" ItemsSource ="{Binding Source={StaticResource key_view_1}}"/>