![](/img/trans.png)
[英]Binding Dictionary Value to Dependency Property of a UserControl WPF
[英]How do I reference a custom property value in a WPF UserControl via Binding?
我正在使用自定義 UserControl 構建 WPF 應用程序,並且我正在嘗試了解屬性綁定應該如何工作。 我連最基本的綁定都無法工作,而且它很簡單,可以提煉成一個小例子,所以我認為有更多 WPF 經驗的人可能能讓我走上正軌。
我定義了一個名為TestControl的自定義 UserControl ,它公開了一個Foo屬性,該屬性旨在在放置 UserControl 時在 XAML 中設置。
測試控件.xaml.cs
using System.Windows;
using System.Windows.Controls;
namespace BindingTest
{
public partial class TestControl : UserControl
{
public static readonly DependencyProperty FooProperty = DependencyProperty.Register("Foo", typeof(string), typeof(TestControl));
public string Foo
{
get { return (string)GetValue(FooProperty); }
set { SetValue(FooProperty, value); }
}
public TestControl()
{
InitializeComponent();
}
}
}
TestControl 的標記只是將其定義為具有單個按鈕的控件,其標簽文本顯示 Foo 屬性的當前值:
測試控件.xaml
<UserControl x:Class="BindingTest.TestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BindingTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button Content="{Binding Foo}" />
</Grid>
</UserControl>
在我的MainWindow類中,我只放置了一個 TestControl 實例,其 Foo 屬性設置為“Hello”。
主窗口.xaml
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:TestControl Foo="Hello" />
</Grid>
</Window>
我希望當我構建和啟動這個應用程序時,我會看到一個帶有一個按鈕的窗口,上面寫着“你好”。 但是,按鈕是空白的:綁定似乎不起作用。
如果我向 TestControl 的按鈕添加一個單擊處理程序,我可以驗證該值是否正在幕后更新:
// Added to TestControl.xaml.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("Button clicked; Foo is '{0}'", Foo);
}
// Updated in TestControl.xaml:
// <Button Content="{Binding Foo}" Click="Button_Click" />
當我點擊按鈕時,我Button clicked; Foo is 'Hello'
Button clicked; Foo is 'Hello'
,但 GUI 永遠不會更新。 我試過使用Path=Foo
、 XPath=Foo
等,以及設置UpdateSourceTrigger=PropertyChanged
並使用NotifyOnTargetUpdated=True
驗證更新......似乎沒有任何內容導致 UI 中的文本被更新以匹配底層屬性值,即使屬性值似乎更新得很好。
我究竟做錯了什么? 我覺得我如何處理這個問題只是一個簡單而根本的誤解。
編輯:
多探索一下並閱讀類似的問題讓我找到了一個潛在的解決方法:即,向 TestControl.xaml 中的根 UserControl 元素添加一個名稱( x:Name="control"
),並更改綁定以顯式指定該控件( {Binding Foo, ElementName=control}
)。
我猜默認情況下,Button 元素上的{Binding Foo}
僅表示“在此 Button 控件上找到名為 'Foo' 的屬性” ,而我認為它的意思是“在聲明此 Button 的上下文,即在 TestControl" 上。
在這里指定一個顯式的 ElementName 是最好的解決方法嗎?
您必須將 Binding 的源對象設置為 UserControl 實例,例如:
<Button Content="{Binding Foo, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
或者
<UserControl ... x:Name="theControl">
...
<Button Content="{Binding Foo, ElementName=theControl}"/>
如果您有很多這樣的綁定,您還可以將 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}" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.