C# WPF 用户控件中的数据绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11226843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Data Binding in WPF User Controls
提问by Gabriel Sanmartin
I am creating a UserControl for a series of controls shared by several windows. One of the controls is a Label which shows the flow of some other process in terms of "protocol numbers".
我正在为多个窗口共享的一系列控件创建一个 UserControl。其中一个控件是一个标签,它根据“协议编号”显示一些其他进程的流程。
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.
我正在尝试使用此标签提供数据绑定,以便窗口在协议编号变量更改时自动反映进程的状态。
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:
这是代码隐藏:
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.
这会将协议编号设置为零,忽略设置为编号的值。
I've read example
我读过例子
采纳答案by blindmeis
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.
您遇到的问题如下:在您的用户控件中,您会将标签绑定到用户控件的 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. but you have to bind to the DataContext of the MainWindow with RelativeSource.
编辑:为了清除一些事情,如果您更改 MainWindow 中的绑定,您的用户控件也可以工作。但是您必须使用RelativeSource 绑定到MainWindow 的DataContext。
<expControl:MainControls ProtocolNumber="{Binding Path=Number, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
回答by Mizipzor
If you're not specifying the RelativeSourceof the binding, try set the DataContextin the constructor:
如果您没有指定RelativeSource绑定的 ,请尝试DataContext在构造函数中设置:
public Window1()
{
Number= 15;
DataContext = this;
InitializeComponent();
}
回答by H.B.
What you have in effect:
你有什么效果:
<expControl:MainControls DataContext="{Binding RelativeSource={RelativeSource Self}}"
ProtocolNumber="{Binding Path=Number, Mode=TwoWay}"/>
=> Do notset the DataContextin UserControldeclarations, use RelativeSourceor ElementNamebindings instead.
=>不要没有设定DataContext中UserControl声明,使用RelativeSource或ElementName绑定来代替。

