大理网站建设沛宣,做设计常用网站有哪些,最全微信小程序名单,IDC网站用什么软件建在上一次的文章WPF OnApplyTemplate 不执行 或者执行滞后的疑惑谈到怎么正确的开发自定义控件#xff0c;我们控件的样式中#xff0c;属性的绑定一般都是用TemplateBinding来完成,如下一个基本的按钮样式#xff1a; Style x:KeySimpleButton TargetType我们控件的样式中属性的绑定一般都是用TemplateBinding来完成,如下一个基本的按钮样式 Style x:KeySimpleButton TargetType{x:Type Button} BasedOn{x:Null}Setter PropertyFocusVisualStyle Value{DynamicResource SimpleButtonFocusVisual}/Setter PropertyBackground Value{DynamicResource NormalBrush}/Setter PropertyBorderBrush Value{DynamicResource NormalBorderBrush}/Setter PropertyTemplateSetter.ValueControlTemplate TargetType{x:Type Button}!-- We use Grid as a root because it is easy to add more elements to customize the button --Grid x:NameGridBorder x:NameBorder Background{TemplateBinding Background} BorderBrush{TemplateBinding BorderBrush} BorderThickness{TemplateBinding BorderThickness} Padding{TemplateBinding Padding}/!-- Content Presenter is where the text content etc is placed by the control --!-- The bindings are useful so that the control can be parameterized without editing the template --ContentPresenter HorizontalAlignment{TemplateBinding HorizontalContentAlignment} Margin{TemplateBinding Padding} VerticalAlignment{TemplateBinding VerticalContentAlignment} RecognizesAccessKeyTrue//Grid!--Each state sets a brush on the Border in the template --ControlTemplate.TriggersTrigger PropertyIsKeyboardFocused ValuetrueSetter PropertyBorderBrush Value{DynamicResource DefaultedBorderBrush} TargetNameBorder//TriggerTrigger PropertyIsMouseOver ValuetrueSetter PropertyBackground Value{DynamicResource MouseOverBrush} TargetNameBorder//TriggerTrigger PropertyIsPressed ValuetrueSetter PropertyBackground Value{DynamicResource PressedBrush} TargetNameBorder/Setter PropertyBorderBrush Value{DynamicResource PressedBorderBrush} TargetNameBorder//TriggerTrigger PropertyIsEnabled Valuetrue/Trigger PropertyIsEnabled ValuefalseSetter PropertyBackground Value{DynamicResource DisabledBackgroundBrush} TargetNameBorder/Setter PropertyBorderBrush Value{DynamicResource DisabledBorderBrush} TargetNameBorder/Setter PropertyForeground Value{DynamicResource DisabledForegroundBrush}//Trigger/ControlTemplate.Triggers/ControlTemplate/Setter.Value/Setter
/Style 我们看到许多属性都是用TemplateBinding来完成的也就是我们在使用控件和开发自定义控件时都能够做到数据的展示和数据的行为分开使用数据驱动UI的思想对于较复杂行为的控件我们也可以在OnApplyTemplate方法中通过GetTemplateChild方法来获取到当然这个方法的执行时机是必须在布局过程中如果在这之前就使用了内部的控件那么必然会报Null错误。 所以一般的样式开发中都是用TemplateBinding来完成说说今天的遭遇。我就是开发一个分页控件点击上一页下一页的时候当前的页码要能够跟着变化。显示这个页码的控件那就是TextBlockTemplateBinding了PageIndex依赖属性。控件的后台代码中对上一页下一页的事件就是修改PageIndex的值。运行起来页码不会跟着变化好修改成Binding方式如下 TextBlock Text{Binding RelativeSource{RelativeSource TemplatedParent},PathPageIndex}/TextBlock 这样能够正常工作了。但是WPF自家的控件用的都是TemplateBinding都没这问题不甘心继续网上找资料发现一篇说是自定义的依赖属性使用TemplateBinding就是有问题的这种bug微软怎么能不发现呢并且这都.Net4.5了内心感觉一定不是这样的终于啊找到问题所在了并且是在一篇排版杂乱无章的小博客中找到的。 TemplateBinding作为一种性能优化后的Binding使用据说是Binding比较耗资源这个没有求证过但是我的程序中那么多Binding运行起来也不觉得慢啊或者说是用在模板中的一种Binding优化方式。既然是优化过的那么它就会少一些东西其中一个是数据流动的方向。TemplateBinding是单方向的即数据源到目标的方向。这也解释了TreeViewItem官方的样式中那个三角形的小箭头它对于是否展开IsExpanded属性的属性绑定用的就不是TempalteBinding因为他不能反过去更新数据源啊。 Style x:KeySimpleTreeViewItem d:IsControlPartTrue TargetType{x:Type TreeViewItem}Setter PropertyBackground ValueTransparent/Setter PropertyHorizontalContentAlignment Value{Binding PathHorizontalContentAlignment, RelativeSource{RelativeSource AncestorType{x:Type ItemsControl}}}/Setter PropertyVerticalContentAlignment Value{Binding PathVerticalContentAlignment, RelativeSource{RelativeSource AncestorType{x:Type ItemsControl}}}/Setter PropertyPadding Value1,0,0,0/Setter PropertyTemplateSetter.ValueControlTemplate TargetType{x:Type TreeViewItem}GridGrid.ColumnDefinitionsColumnDefinition MinWidth19 WidthAuto/ColumnDefinition WidthAuto/ColumnDefinition Width*//Grid.ColumnDefinitionsGrid.RowDefinitionsRowDefinition HeightAuto/RowDefinition//Grid.RowDefinitions!--注意这里--ToggleButton x:NameExpander Style{DynamicResource SimpleTreeViewItemToggleButton} IsChecked{Binding PathIsExpanded, RelativeSource{RelativeSource TemplatedParent}} ClickModePress/Border Grid.Column1 x:NameSelection_Border Background{TemplateBinding Background} BorderBrush{TemplateBinding BorderBrush} BorderThickness{TemplateBinding BorderThickness} Padding{TemplateBinding Padding}ContentPresenter HorizontalAlignment{TemplateBinding HorizontalContentAlignment} x:NamePART_Header ContentSourceHeader//BorderItemsPresenter Grid.Column1 Grid.ColumnSpan2 Grid.Row1 x:NameItemsHost//GridControlTemplate.TriggersTrigger PropertyIsExpanded ValuefalseSetter PropertyVisibility ValueCollapsed TargetNameItemsHost//TriggerTrigger PropertyHasItems ValuefalseSetter PropertyVisibility ValueHidden TargetNameExpander//TriggerTrigger PropertyIsSelected ValuetrueSetter PropertyBackground Value{DynamicResource {x:Static SystemColors.HighlightBrushKey}} TargetNameSelection_Border/Setter PropertyForeground Value{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}//TriggerMultiTriggerMultiTrigger.ConditionsCondition PropertyIsSelected Valuetrue/Condition PropertyIsSelectionActive Valuefalse//MultiTrigger.ConditionsSetter PropertyBackground Valuered TargetNameSelection_Border/Setter PropertyForeground Value{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}//MultiTriggerTrigger PropertyIsEnabled ValuefalseSetter PropertyForeground Value{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}//Trigger/ControlTemplate.Triggers/ControlTemplate/Setter.Value/Setter
/Style 但是在分页控件的这个页码属性上是不需要反方向更新数据源这个功能的。所以问题也不是这儿但必须注意这一点开发自定义控件的时候非常重要。 另外一个区别就是ConverterWPF中的Binding都是能够通过Converter来转换数据的所以不管是TemplateBinding还是Binding都是够使用Converter来设置转换器区别在于没有设置转换器的情况下例如将int类型的数据绑定到TextBox的Text属性上Binding会将值转换成字符串来显示然而TemplateBinding就不会这就是页码不能显示也不会变化的原因。我立马弄了一个字符串类型页码依赖属性TemplateBinding到这个Text属性上可以工作了。但不会这么傻再写一个转换器给TemplateBinding这也是能够工作的。所以当数据源的类型和目标的类型不一致时TemplateBinding需要自己写转换器来完成。 总结一下TemplateBinding与Binding区别 1TemplateBinding只是单方向的数据绑定 2TemplateBinding不会自动转换数据类型 转载于:https://www.cnblogs.com/HelloMyWorld/p/6744894.html