为什么这儿TemplateBinding不起作用了—研究WPF Binding(一)
展开全部
工作中,写自定义控件,遇到一个奇怪的问题。场景是这样的:一个ListBox或其他ItemsControl显示数据列表,下方一个TextBlock显示列表中选定的值,代码大概是这样的(做了简化):<BorderBackground={TemplateBinding Background}
BorderBrush={TemplateBinding BorderBrush}
BorderThickness={TemplateBinding BorderThickness}<StackPanel<ListBoxItemsSource={Binding RelativeSource={RelativeSource TemplatedParent},Path=TimeDataSource.Months}
SelectedValue={TemplateBinding Month}
VerticalContentAlignment=Top</ListBox<TextBlockText={TemplateBinding Month}/</StackPanel</Border
Month是后台定义的依赖属性,现在的问题是,ListBox拿到了数据(1到12个月),但下方的TextBlock却显示不出列表的SelectedValue,必须把它的代码换成这样才行:<TextBlockText={Binding RelativeSource={RelativeSource TemplatedParent},Path=Month}/用snoop抓取也会看到后面一种情形,Text属性才能拿到值。显然要查清楚问题所在必须研究一下TemplateBinding。
按照MSDN和网络上看到的解释,TemplateBinding主要用于模版,属于优化的Binding但精简了继承内容引用和动态类型转换等很多功能,它等效于:{Binding RelativeSource={RelativeSource TemplatedParent}}。看到这儿品味出什么了吧,对,类型转换!它所绑定的依赖属性Month是Int类型,而TextBlock的Text属性是String类型,如果用普通Binding,WPF能自动帮你做转换,而TemplateBinding就不行了。无独有偶,几个月前我写过一个小控件,一个要求是输入框(TextBox)前面的文本说明是可以设置的,比如“柜员账号”或其他什么名称,我定义的InputName属性是String类型,用TemplateBinding和TextBlock绑在一起就可以正常运行。那就再定义一个String类型的依赖属性,试试看:publicstaticreadonlyDependencyProperty MonthStringProperty =
DependencyProperty.Register(
MonthString,
typeof(String),
typeof(ControlTest),newFrameworkPropertyMetadata(DateTime.Now.Month.ToString()));publicString MonthString{get{returnGetValue(MonthStringProperty).ToString(); }set{ SetValue(MonthStringProperty, value); }}前台Xaml如下:<BorderBackground={TemplateBinding Background}
BorderBrush={TemplateBinding BorderBrush}
BorderThickness={TemplateBinding BorderThickness}<StackPanel<TextBlockText={TemplateBinding MonthString}/<ListBoxItemsSource={Binding RelativeSource={RelativeSource TemplatedParent},Path=TimeDataSource.Months}
SelectedValue={TemplateBinding Month}
VerticalContentAlignment=Top</ListBox<TextBlockText={Binding RelativeSource={RelativeSource TemplatedParent},Path=Month}/</StackPanel</Border
果然,数据能显示了:
BorderBrush={TemplateBinding BorderBrush}
BorderThickness={TemplateBinding BorderThickness}<StackPanel<ListBoxItemsSource={Binding RelativeSource={RelativeSource TemplatedParent},Path=TimeDataSource.Months}
SelectedValue={TemplateBinding Month}
VerticalContentAlignment=Top</ListBox<TextBlockText={TemplateBinding Month}/</StackPanel</Border
Month是后台定义的依赖属性,现在的问题是,ListBox拿到了数据(1到12个月),但下方的TextBlock却显示不出列表的SelectedValue,必须把它的代码换成这样才行:<TextBlockText={Binding RelativeSource={RelativeSource TemplatedParent},Path=Month}/用snoop抓取也会看到后面一种情形,Text属性才能拿到值。显然要查清楚问题所在必须研究一下TemplateBinding。
按照MSDN和网络上看到的解释,TemplateBinding主要用于模版,属于优化的Binding但精简了继承内容引用和动态类型转换等很多功能,它等效于:{Binding RelativeSource={RelativeSource TemplatedParent}}。看到这儿品味出什么了吧,对,类型转换!它所绑定的依赖属性Month是Int类型,而TextBlock的Text属性是String类型,如果用普通Binding,WPF能自动帮你做转换,而TemplateBinding就不行了。无独有偶,几个月前我写过一个小控件,一个要求是输入框(TextBox)前面的文本说明是可以设置的,比如“柜员账号”或其他什么名称,我定义的InputName属性是String类型,用TemplateBinding和TextBlock绑在一起就可以正常运行。那就再定义一个String类型的依赖属性,试试看:publicstaticreadonlyDependencyProperty MonthStringProperty =
DependencyProperty.Register(
MonthString,
typeof(String),
typeof(ControlTest),newFrameworkPropertyMetadata(DateTime.Now.Month.ToString()));publicString MonthString{get{returnGetValue(MonthStringProperty).ToString(); }set{ SetValue(MonthStringProperty, value); }}前台Xaml如下:<BorderBackground={TemplateBinding Background}
BorderBrush={TemplateBinding BorderBrush}
BorderThickness={TemplateBinding BorderThickness}<StackPanel<TextBlockText={TemplateBinding MonthString}/<ListBoxItemsSource={Binding RelativeSource={RelativeSource TemplatedParent},Path=TimeDataSource.Months}
SelectedValue={TemplateBinding Month}
VerticalContentAlignment=Top</ListBox<TextBlockText={Binding RelativeSource={RelativeSource TemplatedParent},Path=Month}/</StackPanel</Border
果然,数据能显示了:
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询