複数のウィンドウで共有される一連のコントロールのUserControlを作成しています。コントロールの1つは、「プロトコル番号」に関して他のプロセスの流れを示すラベルです。
プロトコル番号変数が変更されると、ウィンドウがプロセスの状態を自動的に反映するように、このラベルでDataBindingを提供しようとしています。
これはユーザーコントロールXAMLです。
<UserControl Name="MainOptionsPanel"
x:Class="ExperienceMainControls.MainControls"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Label Height="Auto" Name="numberLabel">Protocol:</Label>
<Label Content="{Binding Path=ProtocolNumber}" Name="protocolNumberLabel"/>
(...)
</UserControl>
これがコードビハインドです。
public partial class MainControls
{
public MainControls()
{
InitializeComponent();
}
public int ProtocolNumber
{
get { return (int)GetValue(ProtocolNumberProperty); }
set { SetValue(ProtocolNumberProperty, value); }
}
public static DependencyProperty ProtocolNumberProperty =
DependencyProperty.Register("ProtocolNumber", typeof(int), typeof(MainControls));
}
コンストラクターでProtocolNumberを任意の値に設定すると、ユーザーコントロールに反映されるため、これは機能しているようです。
ただし、最後のウィンドウでこのユーザーコントロールを使用すると、データバインディングが壊れます。
XAML:
<Window x:Class="UserControlTesting.Window1"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml" xmlns:expControl="clr-namespace:ExperienceMainControls;Assembly=ExperienceMainControls"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<StackPanel>
<expControl:MainControls ProtocolNumber="{Binding Path=Number, Mode=TwoWay}" />
</StackPanel>
</Window>
ウィンドウのコードビハインド:
public partial class Window1 : Window
{
public Window1()
{
Number= 15;
InitializeComponent();
}
public int Number { get; set; }
}
これにより、プロトコル番号がゼロに設定され、数値に設定された値は無視されます。
私は例を読んだ
出力ウィンドウを見ると、バインディング例外が表示されます。
問題は次のとおりです。ユーザーコントロール内で、ラベルをDataContext
ではなくユーザーコントロールのDP ProtocolNumberにバインドするため、たとえば要素名をバインドに追加する必要があります。
<UserControl Name="MainOptionsPanel"
x:Class="ExperienceMainControls.MainControls"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
x:Name="uc"
>
<Label Height="Auto" Name="numberLabel">Protocol:</Label>
<Label Content="{Binding Path=ProtocolNumber, ElementName=uc}" Name="protocolNumberLabel"/>
(...)
</UserControl>
編集:いくつかのことをクリアするために、MainWindowのバインディングを変更してもユーザーコントロールが機能します。ただし、RelativeSourceを使用してMainWindowのDataContextにバインドする必要があります。
<expControl:MainControls ProtocolNumber="{Binding Path=Number, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
有効なもの:
<expControl:MainControls DataContext="{Binding RelativeSource={RelativeSource Self}}"
ProtocolNumber="{Binding Path=Number, Mode=TwoWay}"/>
=>実行notDataContext
宣言でUserControl
を設定し、代わりにRelativeSource
またはElementName
バインディングを使用します。
バインディングのRelativeSource
を指定していない場合は、コンストラクターでDataContext
を設定してみてください。
public Window1()
{
Number= 15;
DataContext = this;
InitializeComponent();
}