Привязка (Binding). Интерфейс INotifyPropertyChanged. Форматирование значений привязки и конвертеры значений.
Введение в привязку данных
<Window
x:Class="BindingApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingApp"
mc:Ignorable="d"
Title="MainWindow"
Height="250"
Width="300"
>
<StackPanel>
<TextBox
x:Name="myTextBox"
Height="30" />
<TextBlock
x:Name="myTextBlock"
Text="{Binding
ElementName=myTextBox,
Path=Text}"
Height="30" />
</StackPanel>
</Window>
Работа с привязкой в C
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding();
// элемент-источник
binding.ElementName = "myTextBox";
// свойство элемента-источника
binding.Path = new PropertyPath("Text");
// установка привязки для элемента-приемника
myTextBlock.SetBinding(TextBlock.TextProperty, binding);
}
Режимы привязки
<StackPanel>
<TextBox
x:Name="textBox1"
Height="30" />
<TextBox
x:Name="textBox2"
Height="30"
Text="{Binding
ElementName=textBox1,
Path=Text,
Mode=TwoWay}" />
</StackPanel>
Свойство Source
class Phone
{
public string Title { get; set; }
public string Company { get; set; }
public int Price { get; set; }
}
<Window
x:Class="BindingApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingApp"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="300"
>
<Window.Resources>
<local:Phone
x:Key="nexusPhone"
Title="Nexus X5"
Company="Google"
Price="25000" />
</Window.Resources>
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock
Text="Модель:"
Foreground="White"/>
<TextBlock
x:Name="titleTextBlock"
Text="{Binding
Source={StaticResource nexusPhone},
Path=Title}"
Foreground="White"
Grid.Column="1"/>
<TextBlock
Text="Цена:"
Foreground="White"
Grid.Row="1"/>
<TextBlock
x:Name="priceTextBlock"
Text="{Binding
Source={StaticResource nexusPhone},
Path=Price}"
Foreground="White"
Grid.Column="1"
Grid.Row="1"/>
</Grid>
</Window>
Свойство TargetNullValue
<Window.Resources>
<local:Phone
x:Key="nexusPhone"
Company="Google"
Price="25000" />
</Window.Resources>
<StackPanel>
<TextBlock
x:Name="titleTextBlock"
Text="{Binding
Source={StaticResource nexusPhone},
Path=Title,
TargetNullValue=Текст по умолчанию}" />
</StackPanel>
Свойство RelativeSource
<TextBox Text="{Binding
RelativeSource={RelativeSource Mode=Self},
Path=Background,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<Grid Background="Black">
<TextBlock
Foreground="White"
Text="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type Grid}},
Path=Background}" />
</Grid>
Свойство DataContext
<Window
x:Class="BindingApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingApp"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="300">
<Window.Resources>
<local:Phone
x:Key="nexusPhone"
Title="Nexus X5"
Company="Google"
Price="25000" />
</Window.Resources>
<Grid
Background="Black"
DataContext="{StaticResource nexusPhone}"
TextBlock.Foreground="White">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
Text="Модель" />
<TextBlock
Text="{Binding Title}"
Grid.Row="1" />
<TextBlock
Text="Производитель"
Grid.Column="1"/>
<TextBlock
Text="{Binding Company}"
Grid.Column="1"
Grid.Row="1" />
<TextBlock
Text="Цена"
Grid.Column="2" />
<TextBlock
Text="{Binding Price}"
Grid.Column="2"
Grid.Row="1" />
</Grid>
</Window>
Интерфейс INotifyPropertyChanged.
<Window
x:Class="BindingApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingApp"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="300"
>
<Window.Resources>
<local:Phone
x:Key="nexusPhone"
Title="Nexus X5"
Company="Google"
Price="25000" />
</Window.Resources>
<Grid
Background="Black"
DataContext="{StaticResource nexusPhone}"
TextBlock.Foreground="White">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
Text="Модель" />
<TextBlock
Text="{Binding Title}"
Grid.Row="1" />
<TextBlock
Text="Производитель"
Grid.Column="1"/>
<TextBlock
Text="{Binding Company}"
Grid.Column="1"
Grid.Row="1" />
<TextBlock
Text="Цена"
Grid.Column="2" />
<TextBlock
Text="{Binding Price}"
Grid.Column="2"
Grid.Row="1" />
<Button
Foreground="White"
Content="Изменить"
Click="Button_Click"
Background="Black"
BorderBrush="Silver"
Grid.Column="2"
Grid.Row="2" />
</Grid>
</Window>
using System.ComponentModel;
using System.Runtime.CompilerServices;
class Phone : INotifyPropertyChanged
{
private string title;
private string company;
private int price;
public string Title
{
get { return title; }
set
{
title = value;
OnPropertyChanged("Title");
}
}
public string Company
{
get { return company; }
set
{
company = value;
OnPropertyChanged("Company");
}
}
public int Price
{
get { return price; }
set
{
price = value;
OnPropertyChanged("Price");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
Форматирование значений привязки и конвертеры значений
class Phone
{
public string Title { get; set; }
public string Company { get; set; }
public int Price { get; set; }
}
<Window
x:Class="ValueConventerApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ValueConventerApp"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="300"
>
<Window.Resources>
<local:Phone
x:Key="nexusPhone"
Title="Nexus X5"
Company="Google"
Price="25000" />
</Window.Resources>
<Grid>
<TextBlock
Text="{Binding
StringFormat=Итоговая цена {0} рублей,
Source={StaticResource nexusPhone},
Path=Price}" />
</Grid>
</Window>
Конвертеры значений
public class DateTimeToDateConverter : IValueConverter
{
public object Convert(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
if(parameter!=null && parameter.ToString()=="EN")
return ((DateTime)value).ToString("MM-dd-yyyy");
return ((DateTime)value).ToString("dd.MM.yyyy");
}
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
<StackPanel>
<TextBlock
Text="{Binding
Source={StaticResource myDate},
Converter={StaticResource myDateConverter}}" />
<TextBlock
Text="{Binding
Source={StaticResource myDate},
ConverterParameter=EN,
Converter={StaticResource myDateConverter}}" />
<TextBlock
Text="{Binding
Source={StaticResource myDate}}" />
</StackPanel>