【问题标题】:WPF MVVM Dependency PropertiesWPF MVVM 依赖属性
【发布时间】:2013-03-26 20:29:14
【问题描述】:

我有以下情况:

  1. 我有一个用户控件,里面只有一个网格。
  2. Grid 的第一列是复选框列,绑定到 CustomerModel 的 IsSelected 属性
  3. Grid 的 ItemsSource 绑定到 List
  4. 当用户选中任何 CheckBox 时,CustomerModel 的相应 IsSelected 属性正在更新

查询:

  1. 我向 UserControl 添加了一个名为“SelectedCustomerItems”的依赖属性,我希望它返回一个 List(仅适用于 IsSelected = true)

  2. 这个 UserControl 被放置在另一个窗口中

  3. 依赖属性“SelectedCustomerItems”绑定到 WindowViewModel 内的“SelectedCustomers”属性

但是我没有通过这个依赖属性获取 SelectedCustomer 项。断点未命中 Get{} 请建议....

【问题讨论】:

  • 只需将CustomerModel 包装在包含IsSelected 属性的CustomerViewModel 中。您无需将DependencyProperties 放入UI 来保存您的数据。
  • 谢谢 HiCore,我已经有了。我面临的问题是:当我将此用户控制权交给另一个用户时,他如何将 SelectedCustmerItems 从 UserControl 获取到他的 ViewModel
  • “已选择/未选择”不是 View (IMO) 的责任。相反,将CheckBox 绑定到事物的IsSelected 属性。然后是.Where(x => X.IsSelected)的问题。
  • 我同意。我只想让另一个用户从我的用户控件中读取所有选定的数据。怎么做。
  • 对不起,你好像不明白。请发布您当前的代码和 XAML,以便我告诉您如何修复它。

标签: wpf mvvm wpf-controls dependency-properties


【解决方案1】:

以这种方式实现您的 DP:

#region SomeProperty
/// <summary>
/// The <see cref="DependencyProperty"/> for <see cref="SomeProperty"/>.
/// </summary>
public static readonly DependencyProperty SomePropertyProperty =
    DependencyProperty.Register(
        SomePropertyPropertyName,
        typeof(object),
        typeof(SomeType),
        // other types here may be appropriate for your situ
        new FrameworkPropertyMetadata(null, OnSomePropertyPropertyChanged));

/// <summary>
/// Called when the value of <see cref="SomePropertyProperty"/> changes on a given instance of <see cref="SomeType"/>.
/// </summary>
/// <param name="d">The instance on which the property changed.</param>
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void OnSomePropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    (d as SomeType).OnSomePropertyChanged(e.OldValue as object, e.NewValue as object);
}

/// <summary>
/// Called when <see cref="SomeProperty"/> changes.
/// </summary>
/// <param name="oldValue">The old value</param>
/// <param name="newValue">The new value</param>
private void OnSomePropertyChanged(object oldValue, object newValue)
{

}

/// <summary>
/// The name of the <see cref="SomeProperty"/> <see cref="DependencyProperty"/>.
/// </summary>
public const string SomePropertyPropertyName = "SomeProperty";

/// <summary>
/// 
/// </summary>
public object SomeProperty
{
    get { return (object)GetValue(SomePropertyProperty); }
    set { SetValue(SomePropertyProperty, value); }
}
#endregion  

您必须了解,DependencyProperty 不仅仅是添加了一堆垃圾的属性,它是 WPF 绑定系统 的挂钩。这是一个庞大而复杂的系统,位于海平面以下,您的 DP 优雅地漂浮在其上。它的行为方式出乎你的意料,除非你真的学会了它。

您正在体验我们所有人对 DP 的第一个启示:绑定不会通过属性访问器(即 getset 方法)访问 DependencyProperty 值。这些属性访问器是您在代码中使用的便捷方法。您可以省去它们并使用DependencyObject.GetValue and DependencyObject.SetValue,这是系统中的实际挂钩(请参阅上面示例中的 getter/setter 的实现)。

如果您想收听更改通知,您应该按照我在上面的示例中所做的操作。您可以在注册 DependencyProperty 时添加更改通知侦听器。您还可以覆盖继承的 DependencyProperties 的“元数据”(我一直为 DataContext 这样做)以添加更改通知(有些人为此使用 DependencyPropertyDescriptor,但我已经发现他们缺乏)。

但是,无论你做什么,都不要在你的 DependencyProperties 的 getset 方法中添加代码!它们不会被绑定操作执行。

有关 DependencyProperties 工作原理的更多信息,I highly suggest reading this great overview on MSDN.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    相关资源
    最近更新 更多