首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当绑定属性的值不变时,可以说服PropertyChangedCallback运行吗?

当绑定属性的值不变时,可以说服PropertyChangedCallback运行吗?
EN

Stack Overflow用户
提问于 2014-09-01 08:59:04
回答 1查看 1.2K关注 0票数 3

我的应用程序使用MVVM架构,ViewModel不了解视图。当ViewModel对象需要一个新的视图时,它会公开一个公共ShowNewView属性,该属性是一个对象,它的类是基于my ViewModel基类的。WPF视图将自定义DependencyProperty绑定到此,并使用PropertyChangedCallback构造和显示批准窗口。

在第一次设置ShowNewView属性时,所有这些操作都很好。但是,如果用户关闭窗口,然后尝试重新打开窗口,则在引发ShowNewView事件和不调用PropertyChangedCallback时,PropertyChanged属性的值不会更改。

为了“欺骗”DependencyProperty以检测值已经更改(即使存储在ViewModel属性中的值可能没有实际更改),我使用了由Window类公开的SetCurrentValue方法来强制DependencyProperty的值为null

代码语言:javascript
复制
#region ShowNewViewProperty

private static readonly DependencyProperty _ShowNewViewProperty =
    DependencyProperty.RegisterAttached
    (
        "ShowNewView",
        typeof(IRootViewModel),
        typeof(WpfViewWindow),
        new PropertyMetadata(ShowNewViewPropertyChanged)
    );

    public static DependencyProperty ShowNewViewProperty { get { return _ShowNewViewProperty; } }

    public static IRootViewModel GetShowNewView(Window source)
    {
        return (IRootViewModel)source.GetValue(ShowNewViewProperty);
    }

    public static void SetShowNewView(Window target, IRootViewModel value)
    {
        target.SetValue(ShowNewViewProperty, value);
    }

    private static void ShowNewViewPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        WpfViewWindow window = d as WpfViewWindow;
        IRootViewModel newValue = e.NewValue as IRootViewModel;
        if ((null != window) && (null != newValue))
        {
            // Create a child WpfViewWindow.  This method is part of my
            // framework that uses ResourceDictionary entries, imported by MEF
            // to locate the View class corresponding to the ViewModel parameter's
            // class.
            WpfViewWindow modelessWindow = window.CreateWpfViewWindow(newValue);
            if (null != modelessWindow)
            {
                // Show the new WpfViewWindow.
                modelessWindow.Show();
            }

            // Clear the current value so that the next PropertyChanged event
            // is processed even if the underlying value has not actually changed.
            window.SetCurrentValue(ShowNewViewProperty, null);
        }
    }

    #endregion

从技术上讲,这是可行的,因为它会在PropertyChanged事件触发时运行回调,而不管该值是否实际发生了更改。但是,它导致每次更新ViewModel的属性时(递归地)调用回调两次:一次是响应ViewModel的事件,另一次是响应被调用的SetCurrentValue方法。

这里有许多问题涉及到在其他情况下PropertyChangedCallback没有被调用,或者没有被多次调用。

是否有一种更优雅的方法来实现这一点,而不导致对来自PropertyChanged的每个ViewModel事件运行两次回调?也就是说,是否有什么方法可以绕过框架的检查来验证新旧值是否不同?

Clarification

创建的视图不一定总是一个WPF窗口,例如,在我的单元测试中,它是一个模拟,而在项目的后面,它可能是一个精子日志程序集。并不是来自同一个程序集的所有ViewModel对象都是相同的,我们知道将来还需要额外的功能,但是细节目前还没有定义。该应用程序允许用户通过简单的网络连接设备。最初,网络是RS-485之上的ModbusRTU,但是,最终客户可能希望使用CANOpen或Profinet或其他传输层,我必须提供一种插件机制,允许在不改变现有代码的情况下添加新功能。

公平地说,我可以使用几种替代机制来实现相同的结果(即创建ViewModel请求一个新的视图),但我想知道是否有一种方法可以让DependencyPropety‘忘记’以前的值。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-01 09:44:41

这类问题的通常解决方案是从ShowNewViewPropertyChanged方法中提取代码并将其放入另一种方法中:

代码语言:javascript
复制
private void SomeNewMethod(IRootViewModel newValue)
{
    // Create a child WpfViewWindow.  This method is part of my
    // framework that uses ResourceDictionary entries, imported by MEF
    // to locate the View class corresponding to the ViewModel parameter's
    // class.
    WpfViewWindow modelessWindow = CreateWpfViewWindow(newValue);
    if (null != modelessWindow)
    {
        // Show the new WpfViewWindow.
        modelessWindow.Show();
    }

    // Clear the current value so that the next PropertyChanged event
    // is processed even if the underlying value has not actually changed.
    SetCurrentValue(ShowNewViewProperty, null);
}

现在,您可以从ShowNewViewPropertyChanged处理程序和其他任何您想要的地方调用该方法:

代码语言:javascript
复制
private static void ShowNewViewPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    WpfViewWindow window = d as WpfViewWindow;
    IRootViewModel newValue = e.NewValue as IRootViewModel;
    if ((null != window) && (null != newValue))
    {
        window.SomeNewMethod(newValue);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25602238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档