WPF MVVM将用户控件绑定到主窗口视图模型

时间:2013-07-22 05:46:57

标签: wpf mvvm

我在这里问了一段类似的问题WPF MVVM User Control。我得到了一些答案,但他们离开了,所以我想我不清楚我想做什么......

我正在使用MVVM处理WPF应用程序。该应用程序是使用基于组件的方法构建的,因此我有一些我已定义的用户控件将在整个应用程序中使用。举个例子,我有一个地址控件。我想在整个应用程序中使用它多个位置。这是一个例子。见这里:

http://sdrv.ms/1aD775H

带绿色边框的部分是地址控件。该控件具有自己的视图模型。

当我将它放在窗口或其他控件上时,我需要告诉它加载地址的客户的PK。所以我创建了一个Customer ID DependencyProperty:

public partial class AddressView : UserControl
{
    public AddressView()
    {
        InitializeComponent();
    }

    public static DependencyProperty CustomerIdProperty = DependencyProperty.Register("CustomerId", typeof(int), typeof(AddressView),
        new UIPropertyMetadata(0, AddressView.CustomerIdPropertyChangedCallback, AddressView.CustomerIdCoerce, true));


    public int CustomerId
    {
        // THESE NEVER FIRE
        get { return (int)GetValue(CustomerIdProperty); }
        set { SetValue(CustomerIdProperty, value); }
    }

    private static void CustomerIdPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        // THIS NEVER FIRES
        AddressView instance = (AddressView)d;
        instance.CustomerId = (int)args.NewValue;
    }
    enter code here
    private static object CustomerIdCoerce(DependencyObject d, object value)
    {
        return value;   // <=== THIS FIRES ON STARTUP
    }
}

然后在MainWindowView中我有:

<vw:AddressView Grid.Row="1"
                Grid.Column="0"
                x:Name="AddressList"
                CustomerId="{Binding ElementName=TheMainWindow, Path=SelectedCustomer.Id, Mode=TwoWay}"/>

请注意我在用户控件CS中的注释。 Coerce在启动时开火。回调永远不会触发,也不会触发CustomerId getter或setter。

我想要发生的事情似乎很简单,我无法让它发挥作用......

选择客户时,应将CustomerId传递给Address UserControl。然后在地址UserControl的VM中应该处理获取&amp;保存数据。

再次提出2个问题:

1)任何人都看错了什么?

2)UserControl DP如何将PK发送到ViewModel?

如果有人感兴趣,我的示例项目就在这里:http://sdrv.ms/136bj91

由于

2 个答案:

答案 0 :(得分:0)

试试这个:

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

我不确定如何在窗口中管理您选择的项目,因此请相应更改yourSelectedItem.TheProperty

答案 1 :(得分:0)

在这种情况下,你的CustomerId吸气器和安装器永远不会发射。如果希望从后面的代码中访问CustomerIdProperty属性,它们就像帮助方法一样。

您的CustomerIdPropertyChangedCallback方法不会触发,因为您的绑定表达式不正确。您需要绑定到DataContext的{​​{1}}而不是窗口本身:

MainWindow

此外,请确保在绑定到... CustomerId="{Binding ElementName=TheMainWindow, Path=DataContext.SelectedCustomer.Id}" ... 的属性发生更改时调用INotifyPropertyChanged PropertyChanged事件。