简体   繁体   English

WPF用户控件中的数据绑定

[英]Data Binding in WPF User Controls

I am creating a UserControl for a series of controls shared by several windows. 我正在为几个窗口共享的一系列控件创建一个UserControl。 One of the controls is a Label which shows the flow of some other process in terms of "protocol numbers". 其中一个控件是Label,它根据“协议编号”显示其他一些过程的流程。

I am trying to offer DataBinding with this Label so the Window automatically reflects the state of the process as the protocol number variable changes. 我正在尝试使用此Label提供DataBinding,因此Window会在协议编号变量更改时自动反映进程的状态。

This is the User control XAML: 这是用户控件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>

And this is the Code-Behind: 这就是Code-Behind:

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));
}

This seems to be working because if on the constructor I set ProtocolNumber to an arbitrary value, it is reflected in the user control. 这似乎是有效的,因为如果在构造函数中我将ProtocolNumber设置为任意值,它将反映在用户控件中。

However, when using this usercontrol on the final window, the data binding breaks. 但是,在最终窗口上使用此用户控件时,数据绑定会中断。

XAML: 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>

Code-Behind for window: 窗口的代码隐藏:

public partial class Window1 : Window
{
    public Window1()
    {
        Number= 15;
        InitializeComponent();
    }

    public int Number { get; set; }
}

This sets the Protocol Number to zero, ignoring the value set to Number. 这会将协议编号设置为零,忽略设置为Number的值。

I've read example 我看过这个例子

if you look at your output window you should see the binding exception. 如果你查看输出窗口,你应该看到绑定异常。

The problem you have is the following: within your usercontrol you will bind the label to the DP ProtocolNumber of your usercontrol and not the DataContext , so you have to add for example the element name to the binding. 您遇到的问题如下:在您的usercontrol中,您将标签绑定到usercontrol的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>

EDIT: to clear some things up, your usercontrol also works if you change the binding in your MainWindow. 编辑:要清除一些内容,如果更改MainWindow中的绑定,则usercontrol也可以正常工作。 but you have to bind to the DataContext of the MainWindow with RelativeSource. 但是你必须使用RelativeSource绑定到MainWindow的DataContext。

    <expControl:MainControls ProtocolNumber="{Binding Path=Number, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />

What you have in effect: 你有什么效果:

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

=> Do not set the DataContext in UserControl declarations, use RelativeSource or ElementName bindings instead. => 不要设置DataContextUserControl的声明,使用RelativeSourceElementName绑定来代替。

If you're not specifying the RelativeSource of the binding, try set the DataContext in the constructor: 如果您没有指定绑定的RelativeSource ,请尝试在构造函数中设置DataContext

    public Window1()
    {
        Number= 15;
        DataContext = this;
        InitializeComponent();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM