【问题标题】:WPF MVVM Bind User Control to Main Window View ModelWPF MVVM 将用户控件绑定到主窗口视图模型
【发布时间】:2013-07-22 05:46:56
【问题描述】:

我不久前在这里WPF MVVM User Control 提出了类似的问题。我得到了一些答案,但它们离我很远,所以我想我并不清楚我想做什么......

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

http://sdrv.ms/1aD775H

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

当我将它放在窗口或其他控件上时,我需要告诉它要为其加载地址的客户的 PK。所以我创建了一个客户 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 中的 cmets。 Coerce 在启动时触发。回调永远不会触发,CustomerId getter 或 setter 也不会触发。

我想要发生的事情看起来很简单,我就是做不到......

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

所以,再次提出两个问题:

1) 有人知道出了什么问题吗?

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

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

谢谢

【问题讨论】:

  • try adding UpdateSourceTrigger=PropertyChanged to your binding, when the selection changes your control won't get updated otherwise.
  • 你能发布你的usercontrol xaml页面的代码吗..
  • WPF MVVM User Control 的可能副本

标签: wpf mvvm


【解决方案1】:

在这种情况下,您的 CustomerId getter 和 setter 永远不会触发。它们只是作为辅助方法存在,以防想要从您的代码后面访问CustomerIdProperty 属性。

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

...
CustomerId="{Binding ElementName=TheMainWindow, Path=DataContext.SelectedCustomer.Id}"
...

此外,请确保在绑定到 ComboBox 的属性发生更改时调用 INotifyPropertyChanged PropertyChanged 事件。

【讨论】:

    【解决方案2】:

    试试这个:

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

    我不知道如何管理您在窗口中选择的项目,所以请相应地更改yourSelectedItem.TheProperty

    【讨论】:

    • 好的,这有效 - 但只有一次。回调方法仅在第一次选择客户时触发。
    • 你能在代码中粘贴你的 SelectedItem 的实现吗
    • 当然,我创建了一个小型沙盒项目来学习这一点。在这里sdrv.ms/13fM5EY
    猜你喜欢
    • 2013-12-13
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2011-10-07
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    相关资源
    最近更新 更多