Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何通过绑定引用WPF UserControl中的自定义属性值?_C#_Wpf_Xaml_Binding_User Controls - Fatal编程技术网

C# 如何通过绑定引用WPF UserControl中的自定义属性值?

C# 如何通过绑定引用WPF UserControl中的自定义属性值?,c#,wpf,xaml,binding,user-controls,C#,Wpf,Xaml,Binding,User Controls,我正在构建一个带有自定义用户控件的WPF应用程序,并试图了解属性绑定应该如何工作。我甚至连最基本的绑定都做不到,而且它很简单,可以提炼成一个小例子,所以我认为有更多WPF经验的人可能会让我走上正确的道路 我已经定义了一个名为TestControl的自定义UserControl,它公开了一个Foo属性,该属性打算在放置UserControl时在XAML中设置 TestControl.xaml.cs 使用System.Windows; 使用System.Windows.Controls; 命名空间绑

我正在构建一个带有自定义用户控件的WPF应用程序,并试图了解属性绑定应该如何工作。我甚至连最基本的绑定都做不到,而且它很简单,可以提炼成一个小例子,所以我认为有更多WPF经验的人可能会让我走上正确的道路

我已经定义了一个名为TestControl的自定义UserControl,它公开了一个Foo属性,该属性打算在放置UserControl时在XAML中设置

TestControl.xaml.cs

使用System.Windows;
使用System.Windows.Controls;
命名空间绑定测试
{
公共部分类TestControl:UserControl
{
public static readonly dependencProperty FooProperty=dependencProperty.Register(“Foo”、typeof(string)、typeof(TestControl));
公共字符串Foo
{
获取{return(string)GetValue(FooProperty);}
set{SetValue(FooProperty,value);}
}
公共测试控制()
{
初始化组件();
}
}
}
TestControl的标记仅将其定义为具有单个按钮的控件,其标签文本显示Foo属性的当前值:

TestControl.xaml


在我的MainWindow类中,我只放置了一个TestControl实例,其Foo属性设置为“Hello”

main window.xaml


我希望当我构建并启动这个应用程序时,我会看到一个窗口,上面有一个按钮,上面写着“你好”。但是,按钮是空的:绑定似乎不起作用

如果我向TestControl的按钮添加一个click处理程序,我可以验证该值是否正在幕后更新:

//添加到TestControl.xaml.cs:
私有无效按钮\u单击(对象发送者,路由目标e)
{
WriteLine(“单击按钮;Foo是{0}'”,Foo);
}
//在TestControl.xaml中更新:
// 
当我点击按钮时,我会点击
按钮;Foo是“Hello”
,但GUI从不更新。我尝试过使用
Path=Foo
XPath=Foo
等,以及设置
UpdateSourceTrigger=PropertyChanged
并使用
NotifyOnTargetUpdated=True
验证更新。。。似乎没有任何东西会导致UI中的文本被更新以匹配基础属性值,即使属性值似乎得到了很好的更新

我做错了什么?我觉得在我处理这件事的过程中,有一个简单而根本的误解

编辑:

仔细研究和阅读之后,我找到了一个潜在的解决方案:即,在TestControl.xaml(
x:name=“control”
)中向根UserControl元素添加一个名称,并更改绑定以显式指定该控件(
{binding Foo,ElementName=control}

我猜测,默认情况下,Button元素上的
{Binding Foo}
仅表示“在这个按钮控件上查找名为'Foo'的属性”,而我假设它的意思是“在声明这个按钮的上下文中,即在TestControl上查找名为'Foo'的属性”


指定显式元素名是这里的最佳解决方案吗?

您必须将绑定的源对象设置为UserControl实例,例如:

<Button Content="{Binding Foo, RelativeSource={RelativeSource AncestorType=UserControl}}"/>


...

如果有许多这样的绑定,还可以将UserControl的XAML中顶级元素的DataContext设置为UserControl实例:

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
    <Button Content="{Binding Foo}" />
    <Button Content="{Binding Bar}" />
</Grid>


但是,您必须避免设置UserControl的DataContext(这通常是“专家”博客作者推荐的),因为这会破坏UserControl属性的基于DataContext的绑定,如

<local:TestControl Foo="{Binding SomeFoo}" />


漂亮!覆盖整个控件的DataContext是我希望可能的方法。一般来说,绑定具有“DataContext”的概念是我所缺少的难题中的一部分。感谢您对UserControl/DataContext陷阱的修复、词汇表和提示。覆盖整个控件的DataContext正是您应该避免的!看看上面的解释。啊,我可以看出我的措辞会有多么误导。我只是指第二个示例,即在根控件下的顶级元素(即本例中的网格)上设置DataContext。
<local:TestControl Foo="{Binding SomeFoo}" />