43

我正在为多个窗口共享的一系列控件创建一个 UserControl。其中一个控件是一个标签,它以“协议号”的形式显示一些其他过程的流程。

我正在尝试使用此标签提供 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; }
}

这会将协议编号设置为零,忽略设置为编号的值。

我读过例子

4

3 回答 3

50

如果您查看输出窗口,您应该会看到绑定异常。

您遇到的问题如下:在您的用户控件中,您会将标签绑定到您的用户控件的 DP ProtocolNumber 而不是DataContext,因此您必须将例如元素名称添加到绑定中。

<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}}}" />
于 2012-06-27T13:18:14.797 回答
8

你有什么效果:

<expControl:MainControls DataContext="{Binding RelativeSource={RelativeSource Self}}"
                         ProtocolNumber="{Binding Path=Number, Mode=TwoWay}"/>

=> 不要设置inDataContext声明UserControl、使用RelativeSourceElementName绑定。

于 2012-06-27T13:05:52.877 回答
3

如果您没有指定RelativeSource绑定,请尝试DataContext在构造函数中设置:

    public Window1()
    {
        Number= 15;
        DataContext = this;
        InitializeComponent();
    }
于 2012-06-27T13:05:43.100 回答