初期化時にコントロールが表示されない場合、ユーザー コントロールの 1 つでバインドが適切に設定されないという問題が発生しました。この問題は、次の単純化されたコントロールで再現しました。
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 ボックスに表示されると予想されます。最初に折りたたまれた 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 がロードされた後にこのエラーが発生することがわかります。ダミー 3 は、表示されるまで読み込まれません。