0

我正在写一个可以在任何地方使用的值输入控件。控件本身有一个视图模型,它像往常一样设置为其 DataContext。但是当我在父控件中使用控件时,例如:

<UserControl x:Class="X.Y.Z.ParentControl">
    ...
    <local:ValueInput Value="{Binding Path=MyValue}" />
    ...
</UserControl>

我打算将's的MyValue属性绑定到控件,但是 WPF 告诉我它在类中找不到该属性,这是控件本身的视图模型。为什么 WPF 从 child's 中寻找价值?ParentControlDataContextValueInputMyValueValueInputViewModelValueInputDataContext

我只想写一个可以像这样使用的控件:

<telerik:RadNumericUpDown Value="{Binding Path=NumberValue}" />

NumberValue属性在父级中定义DataContext,而不是在控件中。这种模式适用于 Teleriks 控制,但不适用于我的控制。

我该怎么办?

4

2 回答 2

1

对于任何 FrameworkElement,只能有 1 个 DataContext。

如果 UserControl 有自己的 DataContext,则不能使用父级的 DataContext。

但是,您可以使用 RelativeSource 走到父级并获取其 DataContext(每次您需要引用父级的 DataContext)

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type Window}}, Path=DataContext.NumberValue}"

要使此示例正常工作,Parent(任何级别的根)应该是 Window。如果是用户控件,

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type UserControl}}, Path=DataContext.NumberValue}"

代码来自fiq提供的这个链接

于 2012-05-11T03:58:52.307 回答
0

我的朋友告诉我不要DataContext在独立控件中用作视图模型,因为 DataContext 很容易被覆盖 -ViewModel在 XAML 中定义属性和绑定可以解决问题。这是一个例子:

查看模型类:

public class MyValueInputViewModel
{
    public string MyText { get; set; }
}

后面的代码:

public partial class MyValueInput : UserControl
{
    public MyValueInput()
    {
        InitializeComponent();

        this.ViewModel = new MyValueInputViewModel
        {
            MyText = "Default Text"
        };
    }

    public static readonly DependencyProperty ViewModelProperty =
        DependencyProperty.Register("ViewModel", typeof(MyValueInputViewModel), typeof(MyValueInput));

    public MyValueInputViewModel ViewModel
    {
        get
        {
            return (MyValueInputViewModel)this.GetValue(ViewModelProperty);
        }
        private set
        {
            this.SetValue(ViewModelProperty, value);
        }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(MyValueInput), new PropertyMetadata(OnValuePropertyChanged));

    private static void OnValuePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
    {
        var input = (MyValueInput)o;
        input.ViewModel.MyText = input.Value;
    }

    public string Value
    {
        get { return (string)this.GetValue(ValueProperty); }
        set { this.SetValue(ValueProperty, value); }
    }
}

XAML:

<UserControl x:Class="..." x:Name="Self" ...>
    <Grid>
        <TextBox Text="{Binding ViewModel.MyText, ElementName=Self, UpdateSourceTrigger=PropertyChanged}" />
    </Grid>
</UserControl>
于 2012-05-11T06:56:20.227 回答