我遇到了一个问题,如果我的一个用户控件在初始化时该控件不可见,则绑定没有正确设置。我用以下简化的控件复制了这个问题:
public class Test3 : Control
{
static Test3()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Test3), new FrameworkPropertyMetadata(typeof(Test3)));
}
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof(string),
typeof(Test3), new UIPropertyMetadata("test3 default text"));
}
public class Test2 : Control
{
static Test2()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Test2), new FrameworkPropertyMetadata(typeof(Test2)));
}
public FrameworkElement Test3Control
{
get { return (FrameworkElement)GetValue(Test3ControlProperty); }
set { SetValue(Test3ControlProperty, value); }
}
public static readonly DependencyProperty Test3ControlProperty =
DependencyProperty.Register("Test3Control", typeof(FrameworkElement),
typeof(Test2), new UIPropertyMetadata(null));
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof(string), typeof(Test2),
new UIPropertyMetadata("test2 default text"));
}
public partial class Test1 : UserControl
{
public Test1()
{
InitializeComponent();
}
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof(string),
typeof(Test1), new UIPropertyMetadata("test1 default text"));
}
用于用户控件的 XAML:
<UserControl x:Class="Test.Test1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dummy="clr-namespace:WpfTestApplication.Test"
Name="ucThis">
<UserControl.Resources>
<Style TargetType="{x:Type test:Test2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type test:Test2}">
<GroupBox Header="Test2">
<StackPanel>
<TextBox IsEnabled="False" Text="{TemplateBinding Test}"/>
<GroupBox Header="Test3">
<ContentPresenter Content="{TemplateBinding Test3Control}"/>
</GroupBox>
</StackPanel>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<test:Test2 Test="{Binding ElementName=ucThis,Path=Test}">
<test:Test2.Test3Control>
<test:Test3 Test="{Binding ElementName=ucThis,Path=Test}">
<test:Test3.Template>
<ControlTemplate TargetType="{x:Type test:Test3}">
<TextBox IsEnabled="False" Text="{TemplateBinding Test}"/>
</ControlTemplate>
</test:Test3.Template>
</test:Test3>
</test:Test2.Test3Control>
</test:Test2>
</Grid>
</UserControl>
...和主窗口的 XAML(无论如何,它的胆量):
<DockPanel>
<StackPanel>
<TextBox Name="tbInput"/>
<Expander Header="Initially Visible" IsExpanded="True">
<test:Test1 Test="{Binding ElementName=tbInput, Path=Text}" />
</Expander>
<Expander Header="Initially Collapsed" IsExpanded="False">
<test:Test1 Test="{Binding ElementName=tbInput, Path=Text}" />
</Expander>
</StackPanel>
</DockPanel>
我希望在文本框(“tbInput”)中输入的任何文本都将显示在 Test2 和 Test3 框中 - 实际上它适用于 Test2 的两个实例,但仅适用于最初可见的 Test3。最初折叠的 Test3 始终显示默认文本,即使在输入文本时它是可见的。
我尝试使用 Snoop 对此进行调查,但是当我使用 Snoop 评估树的相关部分时,问题会自行纠正,因此它没有太大帮助。
是什么导致了这种行为?我该如何纠正?我在哪里可以阅读更多关于它的信息?
更新:
通过观察输出窗口,我发现了这个错误信息:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=ucThis'. BindingExpression:Path=Test; DataItem=null; target element is 'Dummy3' (Name=''); target property is 'Test' (type 'String')
通过处理这些控件上的加载和初始化事件,我可以看到这个错误发生在 Dummy1 和 Dummy2 在启动时加载之后。Dummy 3 在可见之前不会加载。