簡體   English   中英

當UserControl具有DataContext時,UserControl的DependencyProperty為null

[英]UserControl's DependencyProperty is null when UserControl has a DataContext

我在視圖中添加了DependencyProperty,並綁定到DependencyProperty,但前提是我沒有同時設置DataContext。

GenericView.xaml

<UserControl x:Class="GenericProject.View.GenericView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
        <TextBox IsEnabled="False" Text="{Binding SomeProperty, Mode=OneWay}" />
    </StackPanel>
</UserControl>

GenericView.xaml.cs

public partial class GenericView : UserControl
{
    // The DependencyProperty for VMFactory.
    public static readonly DependencyProperty VMFactoryProperty = DependencyProperty.Register("VMFactory", typeof(VMFactoryViewModel<GenericViewModel>), typeof(GenericView));

    public VMFactoryViewModel<GenericViewModel> VMFactory
    {
        get { return (VMFactoryViewModel<GenericViewModel>)GetValue(VMFactoryProperty); }
        set { SetValue(VMFactoryProperty, value); }
    }

    public GenericView()
    {
        InitializeComponent();
    }
}

在這里,我創建兩個視圖來說明當前的問題。 因為我已設置DataContext,所以第一個視圖中的VMFactory綁定將失敗。 第二種觀點會成功,這種現象的原因是什么?

MainPage.xaml

<vw:GenericView DataContext="{Binding Generic}" VMFactory="{Binding GenericFactory}" />
<vw:GenericView VMFactory="{Binding GenericFactory}" />

這是一個相當普通的綁定“陷阱”。

為了訪問VMFactory ,您需要使用...將UserControl綁定到自身。

DataContext="{Binding RelativeSource={RelativeSource Self}}"

然后,您將不會將GenericView項目上的DataContext綁定到其他任何地方。

但是,如果打算將其他值綁定到UserControl外部的VMFactory (即<vw:GenericView VMFactory={Binding ...}"/> ),則應將RelativeSource與模式FindAncestor用於UserControl類型。

<!-- Shortened to show pertinent Binding -->
<ctrl:CommandTextBox Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}"/>

正如@toadflakz所說,這是WPF中的一個非常普遍的問題,當我學習WPF時花了我一些時間來解決這個問題。 幸運的是,解決方案很簡單。 假設我們有一個UserControl ,它有一個對象集作為其DataContext ,另一個集是在UserControl ...中聲明的DependencyProperty的值。

UserControl XAML中,您可以照常將數據綁定到設置為DataContext的對象的屬性:

<TextBlock Text="{Binding PropertyFromDataContextObject}" />

如果要將數據從對象集綁定為DependencyProperty的值,則可以簡單地使用RelativeSource Binding

<TextBlock Text="{Binding PropertyFromDependencyPropertyObject, RelativeSource={
    RelativeSource AncestorType={x:Type YourPrefix:YourUserControl}}}" />

請注意,只要同時設置了DataContextDependencyProperty屬性,就可以在同一UserControl中將這兩個Binding一起使用。

我有一個可行的解決方案,似乎控件的屬性是相對於控件的DataContext綁定的嗎?

我當然知道控件中的項將相對於DataContext進行綁定,但是顯然我以前從未以這種方式使用過控件,並且不了解控件的屬性也將繼承Set DataContext的范圍。 從本質上講,我的視圖中的所有內容都是正確的,但與我的DependencyProperty的綁定失敗。

GenericView.xaml

<!-- Everything in here was correct. -->
<UserControl x:Class="GenericProject.View.GenericView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
        <TextBox IsEnabled="False" Text="{Binding SomeProperty, Mode=OneWay}" />
    </StackPanel>
</UserControl>

MainPage.xaml

<!-- This is where I messed up earlier, VMFactory requires a relative binding. -->
<vw:GenericView DataContext="{Binding Generic}"
                VMFactory="{Binding DataContext.GenericFactory, RelativeSource={RelativeSource AncestorType={x:Type Page}}}" />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM