arc*_*592 7 c# data-binding wpf xaml custom-controls
在构造函数中初始化属性时,我遇到了控件模板内部数据绑定的问题.
这是展示案例(您也可以下载示例解决方案):
CustomControl1.cs
public class CustomControl1 : ContentControl
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CustomControl1),
new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public CustomControl1()
{
Content = "Initial"; // comment this line out and everything
// will start working just great
}
}
Run Code Online (Sandbox Code Playgroud)
CustomControl1风格:
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
CustomControl2.cs:
public class CustomControl2 : ContentControl
{
static CustomControl2()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CustomControl2),
new FrameworkPropertyMetadata(typeof(CustomControl2)));
}
}
Run Code Online (Sandbox Code Playgroud)
CustomControl风格:
<Style TargetType="{x:Type local:CustomControl2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl2}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<local:CustomControl1
Content="{Binding Content,
RelativeSource={RelativeSource
AncestorType=local:CustomControl2}}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
Window1.xaml:
<Window x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
xmlns:local="clr-namespace:WpfApplication5">
<Grid>
<local:CustomControl2 Content="Some content" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
因此,问题是:当您启动应用程序时,CustomControl1的内容似乎是"Initial",它由构造函数设置,而不是"Some content"字符串,应该通过绑定来设置.
当我们从构造函数中删除初始化时,绑定开始工作.
首先,让我预测答案:"你应该在其元数据中设置依赖属性的初始值:在注册时或通过元数据覆盖功能".是的,你是对的,但这种初始化方法的问题是属性是集合类型,所以如果我将提供new MyCustomCollection()属性的默认值,那么每个实例CustomControl1将共享该集合的同一个实例,那就是显然不是这个想法.
我已经对问题做了一些调试,结果如下:
x:Name给它时,它可以通过Template.FindName("PART_Binding", this)内部访问OnApplyTemplate.OnApplyTemplate代码this.GetBindingExpression(ContentProperty)返回的内部相同null.OnApplyTemplate我们可以查找它然后我们可以简单地在它上面设置它:this.SetBinding(ContentProperty, myBinding)- 一切都会正常工作.谁能解释为什么会发生这种情况?
有没有人有一个解决方案来设置依赖属性的非共享初始值,所以绑定不会中断?
提前致谢!
UPD: 最奇怪的是具有最高跟踪级别的调试输出对于两种情况都是相同的:要么在没有发生绑定时,要么就是这样.
在这里:
System.Windows.Data Warning: 52 : Created BindingExpression (hash=18961937) for Binding (hash=44419000)
System.Windows.Data Warning: 54 : Path: 'Content'
System.Windows.Data Warning: 56 : BindingExpression (hash=18961937): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=18961937): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=18961937): Attach to WpfApplication5.CustomControl1.Content (hash=47980820)
System.Windows.Data Warning: 62 : BindingExpression (hash=18961937): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 61 : BindingExpression (hash=18961937): Resolve source deferred
System.Windows.Data Warning: 63 : BindingExpression (hash=18961937): Resolving source
System.Windows.Data Warning: 66 : BindingExpression (hash=18961937): Found data context element: <null> (OK)
System.Windows.Data Warning: 69 : Lookup ancestor of type CustomControl2: queried Border (hash=11653293)
System.Windows.Data Warning: 69 : Lookup ancestor of type CustomControl2: queried CustomControl2 (hash=54636159)
System.Windows.Data Warning: 68 : RelativeSource.FindAncestor found CustomControl2 (hash=54636159)
System.Windows.Data Warning: 74 : BindingExpression (hash=18961937): Activate with root item CustomControl2 (hash=54636159)
System.Windows.Data Warning: 104 : BindingExpression (hash=18961937): At level 0 - for CustomControl2.Content found accessor DependencyProperty(Content)
System.Windows.Data Warning: 100 : BindingExpression (hash=18961937): Replace item at level 0 with CustomControl2 (hash=54636159), using accessor DependencyProperty(Content)
System.Windows.Data Warning: 97 : BindingExpression (hash=18961937): GetValue at level 0 from CustomControl2 (hash=54636159) using DependencyProperty(Content): 'Some content'
System.Windows.Data Warning: 76 : BindingExpression (hash=18961937): TransferValue - got raw value 'Some content'
System.Windows.Data Warning: 85 : BindingExpression (hash=18961937): TransferValue - using final value 'Some content'
Run Code Online (Sandbox Code Playgroud)
UPD2:添加了示例解决方案的链接
| 归档时间: |
|
| 查看次数: |
5334 次 |
| 最近记录: |