当前位置: 首页 > web开发 > ASP.NET > 正文

模板中的 TemplateBinding 问题(4)

时间:2015-04-25 cnblogs 段博琼

4)按钮的 Tap 路由事件:

private void UIElement_OnTap(object sender, GestureEventArgs e)
{
    string temp = WaterPasswordBox.PassText.ToString();
    
    MessageBox.Show(temp);
}

之所以在密码框中输入的文本没有最终传递到 PassText 这个依赖属性上,是因为 TemplateBinding

为 Binding 的单向绑定形式,也就是 依赖属性 PassText 的默认值 “空” 可以绑定到 样式控件里面的

PasswordBox 控件的 Password 属性上,但是 不能反向绑定。

截图:

其中 msdn 对 TemplateBinding 的描述:

“您在模板中使用 TemplateBinding 绑定到模板所应用到的控件的值。      

TemplateBinding    比 Binding 有效,但较少功能。  使用 TemplateBinding 使用与 RelativeSource 属性的 Binding 等效设置为

RelativeSource.TemplatedParent。  ”

“TemplateBinding是Binding的一个轻量级版本,它失去了成熟版本Binding的很多功能,比如继承内容引用(inheritence context referencing),

RelativeSource引用,还有通过IValueConverter/TypeConverter机制的动态类型转换。它仅支持由模板产生的FrameworkElements,它的数据源引

用会指向模板中的父级元素。TemplateBinding最主要的用途是内置在模板中绑定模板化元素的属性,在这种情况下,比起成熟Binding效率要高得多。”

也就是:

<PasswordBox  Password="{TemplateBinding PassText}"/>

等价于:

<PasswordBox  Password="{Binding Path=PassText, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>

这时,把自定义密码框样式中的 PasswordBox 控件的绑定中,把 Binding 的设置 Mode=OneWay 改成 Mode=TwoWay,就可以实现双向绑定了,

截图:

此时虽然完成了双向绑定,但是遇到另一个问题,如果在自定义密码框中输入文本后,立即点击按钮时,弹出框

中显示的还是自定义密码框中之前绑定属性值;如果在填写完成自定义密码框后,单击屏幕其它地方,让密码框

失去焦点,然后再单击按钮,就能显示正确的内容了。

造成这个问题的原因,是因为 这里注册的是按钮的 Tap 这个路由事件,而它的执行时间要早于文本框 LostFocus

事件。这里再为按钮添加一个 Click 事件,为 自定义密码框控件添加一个 LostFocus 事件,同是在 C# 页面打印出

按钮的执行信息:

XAML:

<my:WaterPasswordBox  Name="WaterPasswordBox" LostFocus="WaterPasswordBox_LostFocus"/>
    
 <Button BorderBrush="Blue" Tap="UIElement_OnTap" BorderThickness="5" Margin="0,10" Height="100" Click="Button_Click">
      点击查看断点测试
 </Button>

C# :

private void UIElement_OnTap(object sender, GestureEventArgs e)
 {
     Debug.WriteLine("UIElement_OnTap");
    
     //WaterPasswordBox.PassText = "asd";
     //string temp = WaterPasswordBox.PassText.ToString();
    
     //MessageBox.Show(temp);
 }
    
 private void Button_Click(object sender, RoutedEventArgs e)
 {
     Debug.WriteLine("Button_Click");
    
     string temp = WaterPasswordBox.PassText.ToString();
    
     MessageBox.Show(temp);
 }
    
 private void WaterPasswordBox_LostFocus(object sender, RoutedEventArgs e)
 {
     Debug.WriteLine("WaterPasswordBox_LostFocus");
 }

更多精彩内容:http://www.bianceng.cn/webkf/aspx/