220 likes | 471 Views
Классы Windows Presentation Foundation. Привязка данных ( Data Binding). Механизм привязки данных – программная модель для установления связи между элементом управления и данными приложения . Привязка данных WPF устанавливает связь между
E N D
Привязка данных (Data Binding) • Механизм привязки данных – программная модель дляустановления связи между элементом управления и данными приложения. • Привязка данных WPF устанавливает связь между • свойством (зависимости) элемента управления и свойством отдельного объекта приложения, в том числе и другого элемента управления; • свойством элемента управления и свойством текущего элемента в списке объектов. • WPF поддерживает привязку свойств зависимостей элементов управления к различным источникам данных - к объектам CLR, включая объекты ADO.NET, к данным XML и объектам, связанным с веб-службами . • Привязку можно настроить таким образом, чтобы при изменении данных автоматически обновлялись данные в источнике и элементах управления, если данные предоставляют соответствующие уведомления. • Привязку можно определить как в коде, так и в разметке. • Модель привязки данных WPF похожа на модельпривязки данных Windows Forms. Концепция модели не изменилась, появилась дополнительная функциональность, модель стала более гибкой.
Компоненты привязки • Привязка включает в себя как обязательные компоненты • объект-источник данных (data source) и его свойство, с которым будет установлена связь; • объект-приемник данных(data target)и его свойство (целевое свойство привязки), которое должно быть свойством зависимостей. • При выполнении привязки дополнительно можно определить • направление передачи данных; • момент обновления данных; • пользовательские методы преобразования данных при обмене данными между источником и приемником; • пользовательские методы проверки корректности данных при обмене данными между источником и приемником. • Большая часть этой информации передается модулю управления механизмом привязки WPF (WPF binding engine) через объект одного из классов Binding, MultiBindingили PriorityBinding.
Классы для работы с привязками • Класс Binding описывает привязку для одного свойства источника данных. Класс Binding не содержит информации о целевом объекте привязки. • Класс BindingExpression поддерживает соединение между источником привязки и целью привязки. • Класс BindingOperationsсодержит статические методы для управления привязками. • Классы Validation, ValidationRuleи ValidationResultподдерживают правила проверки корректности данных в привязке.
Как указать источник данных • Источник данных в привязке можно задать явно через свойства Source, ElementNameили RelativeSource класса Binding или унаследовать по умолчанию от свойства DataContext. • Можно установить значение только для одного из трех свойств ElementName, Sourceили RelativeSource, в противном случае будет брошено исключение.
Свойство Path класса Binding public PropertyPathPath { get; set; } • Через свойство Pathобъекта Bindingможно передать • имя свойства объекта-источника данных; • имя свойства в случае, когда сам источник данных является свойством объекта- источника. • Класс PropertyPath используется для описания свойств в привязке данных.В классе определены два конструктора и два свойства:
Привязка в коде. Пример • В примерах источником данных является объект mdiкласса DataItem. • Привязка устанавливает связь между свойством Textэлемента управления TextBoxи свойством Dateобъекта mdiтипа DataItem. class DataItem : INotifyPropertyChanged { private string text; private double doubleValue; public DateTime Date { get; set; } public Point Point { get; set; } public Color Color { get; set; } public event PropertyChangedEventHandlerPropertyChanged; public string Text { get { return text; } set { text = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Text")); } } public double DoubleValue { get { return doubleValue; } set {doubleValue = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("DoubleValue")); } } [ …code …] } Binding bd1 = new Binding(); bd1.Source = mdi; bd1.Path = new PropertyPath("Date"); textBox_1.SetBinding(TextBox.TextProperty, bd1); • Привязка устанавливает связь между свойством DoubleValueобъекта mdiтипа DataItem и свойствами Valueэлемента управления Sliderи Text элемента управления TextBox. Binding bd2 = new Binding(); bd2.Source = mdi; bd2.Path = new PropertyPath("DoubleValue"); slider_1.SetBinding(Slider.ValueProperty, bd2); textBox_2.SetBinding(TextBox.TextProperty, bd2);
Источник данных, унаследованный от DataContext • По умолчанию привязка наследует контекст данных, установленный через свойство DataContext элемента управления. • Свойство DataContextопределено в классе FrameworkElement. public Object DataContext { get; set; } • Свойство DataContextявляется свойством зависимостей и может наследовать значение свойства родительского элемента - если для элемента управления локально или через стиль не установлено значение свойства DataContext, для него будет использовано значение из ближайшего родительского элемента. • Явно указанный в привязке источник данных заменяет унаследованный контекст данных. • В примере контекст данных определен для главного окна приложения. В привязке для элемента управления textBox_11 не указан источник данных, поэтому как источник используется mdi_2, который унаследован от родительского элемента управления как DataContext. this.DataContext = mdi_2; Binding bd = new Binding(); bd.Path = new PropertyPath("Text"); textBox_11.SetBinding(TextBox.TextProperty, bd);
Привязкав XAML. Пример • В примере одним источником данных является объект пользовательского типа DataItem, который был добавлен в словарь ресурсов главного окна приложения с ключом mdi_Key1. • Этот объект использован как значение свойства DataContextродительского элемента Grid, а затем его свойства DoubleValueи Textуказаны в привязках к элементам управления Sliderи TextBox. • Для второго элемента управления TextBoxкак источник в привязках используется объект DataItemс ключом mdi_Key2. Этот объект установлен как значение свойства DataContextсамого элемента TextBox. Его свойстваDateи Brush связываются со свойствами Textи Foreground элемента управления. <Grid Height="317" Width="636" DataContext="{StaticResourcemdi_Key1}"> […code…] <Slider Value="{Binding DoubleValue}" Height="30" Margin="10,210,10,0“ Grid.Column="1" /> <TextBox Text ="{Binding Text}" Height="45" Margin="50,250,50,0“ /> <TextBoxDataContext="{StaticResourcemdi_Key2}" Text="{Binding Date}" Foreground="{Binding Brush}" Grid.Column="3" Height="25" Margin="10,20,12,0“ /> </Grid>
Класс ObjectDataProvider • Класс ObjectDataProvider дает возможность создать в XAML объект пользовательского типа, который инициализируется с использованием конструктора с параметрами. Созданный объект можно использовать в качестве источника привязки в XAML. • В классе ObjectDataProviderопределены свойства : • ConstructorParameters для передачи параметров в конструктор объекта; • MethodName для вызова метода и MethodParameters для передачи параметров в этот метод.
Класс ObjectDataProvider. Пример • В примерев ресурсах главного окна создается объект DataItem, в классе которого определен конструктор с 4 параметрами. С помощью класса ObjectDataProvider параметрам конструктора передаются значения. • Типы string, double иDateTimeнаходятся в сборке mscorlib.dllв пространстве именSystem. С этим пространством имен в открывающем тэге элемента связан префикс system: . • ТипPointнаходится в сборке WindowsBase.dllв пространстве именSystem.Windows. С этим пространством имен связан префикс spt: . <Window.Resources> <ObjectDataProvider x:Key="mdi_Key3" ObjectType="{x:Type zz:DataItem} " xmlns:system="clr-namespace:System;assembly=mscorlib " xmlns:spt="clr-namespace:System.Windows;assembly=WindowsBase"> <ObjectDataProvider.ConstructorParameters> <system:String>ObjectDataProvider</system:String> <system:Double>1.234567</system:Double> <spt:Point>23,23</spt:Point> <system:DateTime>2009/04/07</system:DateTime> </ObjectDataProvider.ConstructorParameters> </ObjectDataProvider> </Window.Resources> • С объектом связан ключ mdi_Key3, который используется в привязках.
Как указать целевой объект привязки в коде • В классах FrameworkElementи FrameworkContentElement определены методы SetBinding и GetBindingExpression – методы-оболочки, которые вызывают одноименные статические методы класса BindingOperations.
Направление привязки • Направление потока данных в привязке управляется свойством Mode класса Binding. public BindingMode Mode { get; set; } • Свойство принимает одно из значений перечисления BindingMode и определяет направление, в котором передаются данные. • В режимах OneWay и TwoWay автоматическое обновление элементов управления при изменении данных в источнике работает только в том случае, когда источник данных реализует интерфейс INotifyPropertyChanged.
Момент обновления значенияв источнике • Привязки в режимах TwoWay и OneWayToSource обновляют данные в источнике в ответ на изменение свойства целевого элемента управления. • Момент обновления источника управляется значением свойства UpdateSourceTrigger класса Binding. public UpdateSourceTrigger UpdateSourceTrigger { get; set; } • Свойство принимает одно из значений перечисления UpdateSourceTrigger: • Значением по умолчанию для UpdateSourceTrigger для большинства свойств зависимостей является PropertyChanged. • Значением по умолчанию для свойства Text в TextBoxявляется LostFocus, так как обновление источника после ввода каждого символа уменьшает производительность.
Класс BindingExpression • Класс Binding описывает привязку для отдельного свойства источника данных и дает возможность настроить характеристики привязки. Класс Binding не содержит информации о целевом объекте привязки. • Связь между источником и целевым объектом поддерживает экземпляр класса BindingExpression. • Один и тот же объект Binding можно использовать для создания нескольких привязок. Для каждой из них будет создан экземпляр BindingExpression, все они будут совместно использовать один и тот же объект Binding. • Ссылку на объект BindingExpression можно получить как возвращаемое значение метода GetBindingExpression класса BindingOperations или класса FrameworkElement. • Методы класса BindingExpressionдля явного обмена данными между источником и приемником:
Класс BindingExpression. Информация о привязке • В классе BindingExpressionопределены свойства с информацией о привязке и ее состоянии. • Некоторые свойства класса BindingExpression.
Класс BindingOperations • Класс предоставляет статические методы для работы с привязками.
Преобразователи значений (converters) • Механизм привязки по умолчанию использует преобразователь (default converter), который выполняет преобразование значений при передаче данных из источника в приемник. Если преобразование выполнить нельзя возвращается значение null. • Пользовательское преобразование значений для привязки определяется в методах Convertи ConvertBack классов, реализующих интерфейс IValueConverter. • ИнтерфейсIValueConverter: public interface IValueConverter { Object Convert( Object value, Type targetType, Object parameter, CultureInfo culture ); Object ConvertBack( Object value, Type targetType, Object parameter, CultureInfo culture ); } • Механизм привязки данных WPF вызывает метод Convertпри передаче данных из источника в приемник и метод ConvertBack при передаче данных в обратном направлении. • Привязка не перехватывает исключения, брошенные пользовательскими преобразователями, они трактуются как ошибки времени выполнения. • Если преобразователь значений не смог выполнить преобразование следует использовать в качестве возвращаемого значения DependencyProperty.UnsetValue, тогда механизм привязки данных используетзначение FallbackValue, если оно определено, и значение default в противном случае.
Преобразователи значений. Пример • В примере определен класс PointConverter, реализующий интерфейс IValueConverter,который выполняет пользовательское преобразование объектов типаPointк типу string. • Для обратного преобразования используется преобразование по умолчанию. [ValueConversion(typeof(Point), typeof(string))] class PointConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Point pt = (Point)value; return " x=" + pt.X + " y=" + pt.Y; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } }
Преобразователи значений. Пример (продолжение) • Объект класса PointConverter, добавлен в словарь ресурсов главного окна приложения с ключом ptConverter_Key. <Window x:Class="Wpf_Binding_1_xaml.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:yy="clr-namespace:Wpf_Binding_1" Title="Window1" Height="414" Width="498" Loaded="Window_Loaded"> <Window.Resources> <yy:PointConverter x:Key="ptConverter_Key"/> </Window.Resources> […code…] </ Window> • Преобразователь с ключом ptConverter_Keyиспользуетсяв привязке для элемента управления TextBox. <TextBox Text="{Binding Path=Point, Converter={StaticResourceptConverter_Key}}" Height="25" Margin="10,130,10,0" Name="textBox_13”/>
Свойства класса Binding для определения пользовательских преобразователей значений • Информация о пользовательском преобразователе передается через свойства объекта Binding: • Использование в коде преобразователя значений из предыдущего примера : Binding bd = new Binding(); bd.Path = new PropertyPath("Point"); bd.Converter = new PointConverter(); textBox_conv_2.SetBinding(TextBox.TextProperty, bd);
Свойство FallbackValue класса Binding public Object FallbackValue { get; set; } • Свойство определяет значение для случая, когда привязка не может вернуть значение. Значение по умолчанию равноDependencyProperty.UnsetValue. • Привязка возвращает значение, если • путь к источнику данных успешно определен (resolve); • преобразователь значений, если он определен, может выполнить преобразование; • результирующее значение является корректным значением целевого свойства приемника.