6.3 Binding的源与路径
如果想让作为Binding源的对象具有自动通知Binding自己的属性值已经变化的能力,那么就需要让类实现INotifyPropertyChanged接口并在属性的set语句中激发PropertyChanged事件。
6.3.1 把控件作为Binding源与Binding标记扩展
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
</Grid.RowDefinitions>
<TextBox x:Name="textBox1" BorderBrush="Black" Grid.Row="0"/>
<TextBox x:Name="textBox2" BorderBrush="Black" Grid.Row="2" Text="{Binding Path=Text, ElementName=textBox1, Mode=OneWay}"/>
</Grid>
6.3.2 控制Binding的方向及数据更新
控制Binding数据流向的属性是Mode,它的类型是BindingMode枚举。BindingMode可取值为TwoWay、OneWay、OnTime、OneWayToSource和Default。这里的Default值是指Binding的模式会根据目标的实际情况来确定,比如若是可编辑的(如TextBox的Text属性),Default就采用双向模式;若是只读的(如TextBlock.Text)则采用单向模式。
UpdateSourceTrigger的类型是UpdateSourceTrigger枚举,可取值为PropertyChanged、LostFocas、Explicit和Default。显然,对于TextBox的默认值Default的行为和LostFocus一致。
<TextBox x:Name="textBox1" BorderBrush="Black" Grid.Row="0"/>
<TextBox x:Name="textBox2" BorderBrush="Black" Grid.Row="2" Text="{Binding Path=Text, ElementName=textBox1, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"/>
6.3.3 Binding的路径(Path)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
<RowDefinition Height="25"/>
<RowDefinition Height="5"/>
</Grid.RowDefinitions>
<TextBox x:Name="textBox1" BorderBrush="Black" Grid.Row="0" TextChanged="textBox1_TextChanged"/>
<TextBox x:Name="textBox2" BorderBrush="Black" Grid.Row="2" Text="{Binding Path=Text, ElementName=textBox1}"/>
<TextBox x:Name="textBox3" BorderBrush="Black" Grid.Row="4" />
<TextBox x:Name="textBox4" BorderBrush="Black" Grid.Row="6" Text="{Binding Path=Text.Length, ElementName=textBox1, Mode=OneWay}"/>
<TextBox x:Name="textBox5" BorderBrush="Black" Grid.Row="8" />
<TextBox x:Name="textBox6" BorderBrush="Black" Grid.Row="10" Text="{Binding Path=Text[2], ElementName=textBox1, Mode=OneWay}"/>
<TextBox x:Name="textBox7" BorderBrush="Black" Grid.Row="12" />
<TextBox x:Name="textBox8" BorderBrush="Black" Grid.Row="14" />
<TextBox x:Name="textBox9" BorderBrush="Black" Grid.Row="16" />
</Grid>
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
Binding binding1 = new Binding("Text") { Source = this.textBox1 };
BindingOperations.SetBinding(textBox3, TextBox.TextProperty, binding1);
Binding binding2 = new Binding("Text.Length") { Source = this.textBox1, Mode=BindingMode.OneWay };
this.textBox5.SetBinding(TextBox.TextProperty, binding2);
List<string> stringList = new List<string>() { "Tim", "Tom", "Blog" };
this.textBox7.SetBinding(TextBox.TextProperty, new Binding("[2]") { Source = stringList, Mode = BindingMode.OneWay }); //Blog
this.textBox8.SetBinding(TextBox.TextProperty, new Binding("/[2]") { Source = stringList, Mode = BindingMode.OneWay }); //m
this.textBox9.SetBinding(TextBox.TextProperty, new Binding("/") { Source = stringList, Mode = BindingMode.OneWay }); //Tim
}