在不触发 OnPropertyChanged 的​​情况下更新 WPF DataGrid

Posted

技术标签:

【中文标题】在不触发 OnPropertyChanged 的​​情况下更新 WPF DataGrid【英文标题】:Updating WPF DataGrid without firing OnPropertyChanged 【发布时间】:2016-08-30 07:42:08 【问题描述】:

我必须在客户端使用 WPF 进行双向通信,并在服务器和客户端之间使用 WCF 进行通信。分为三个部分:

UI(用户可以在其中输入值,MVVM 模式中的视图) 背后的客户端代码(MVVM 模式中的 ViewModel) 与视图模型对话的远程 WCF 服务器。

当用户在 UI 中键入内容时,由于 WPF 双向数据绑定,视图模型中的值会得到更新。视图模型触发 OnPropertyChanged 事件。侦听此事件后,视图模型将更改通知服务器。 没关系!

走向另一个方向是问题。如果服务器得到更新,我希望用户能够直接在 UI 中看到更改。服务器向视图模型发送数据。视图模型更新属性,以便 UI 可以显示该值。但是在设置此属性时,它会再次触发 OnPropertyChanged 事件,并且更改会再次发送到服务器。这样想:

public int MyProperty

    get
    
        return myProperty;
    
    set
    
        // Essentially, I want to know how to tell when the code enters here from the client typing on the UI, or from the server.
        myProperty = value;
        OnPropertyChanged("MyProperty");
    


public void OnPropertyChanged(string propertyName)

    // send this property and its value to the server.

【问题讨论】:

属性设置器set if (_propValue == value) return; ... 中的简单相等检查应该可以防止可能的循环 正如 Ash 提到的,在 setter 中进行相等检查通常是个好主意。在没有实际更改的情况下引发 xxxChanged 事件可能会产生误导。 这只能解决我的部分问题。如果用户从更新服务器的 UI 更新客户端,则工作正常。问题是当服务器更新客户端时,客户端会显示在 UI 上。当服务器向客户端返回消息时,客户端会更改属性并触发 OnPropertyChanged 事件以更新 UI。但同样的事件也会更新服务器。我不能把两者分开。 @user3685285 抱歉回复晚了。请注意,作为 OP,您会自动收到任何新 cmets 的通知。但是,除非您在 @Name syntax 中包含他们的姓名,否则其他评论者不会 我会避免在每次属性更改时调用外部服务,因为它会导致客户端和服务之间的“闲聊”交互。我可以看到这种方法的一些其他问题:如果客户端和服务之间的延迟增加,您将看到来自先前更改的通知覆盖最新更改。 【参考方案1】:

如果您无法更改服务器并且您正在运行 Caller Information methods 可以提供帮助。

如果您能够修改服务器,则让它使用不同的方法来设置值,但为 UI 绑定到的属性提高 PropertyChanged

public int MyProperty

    get
    
        return myProperty;
    
    set
    
        // Essentially, I want to know how to tell when the code enters here from the client typing on the UI, or from the server.
        myProperty = value;
        OnPropertyChanged("MyProperty");
    


public void OnPropertyChanged(string propertyName)

    // send this property and its value to the server.


private void OnServerChangedMyProperty(int value)

    myProperty = value;
    OnPropertyChanged("MyProperty");
    

更新 - 因为 cmets 不能做代码块

假设您有 3 个属性:SumFirstSecond。每当FirstSecond 更改时,您还需要更新Sum。所以First 的设置器看起来像:

set

    _first = value;
    _sum = _first + _second;
    OnPropertyChanged("First"); //Update bindings to First
    OnPropertyChanged("Sum"); //Update bindings to Sum

Second 的设置器看起来像:

set

    _second = value;
    _sum = _first + _second;
    OnPropertyChanged("Second"); //Update bindings to Second
    OnPropertyChanged("Sum");  //Update bindings to Sum

【讨论】:

但是我只能通过设置它绑定的属性来更新 UI,然后触发消息到服务器。不知道怎么区分。

以上是关于在不触发 OnPropertyChanged 的​​情况下更新 WPF DataGrid的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 中找出 OnPropertyChanged 事件的接收者

Xamarin Forms App Shell OnPropertyChanged 未更新 FlyoutHeader 视图

仅查看Model OnPropertyChanged上的更新,但不查看ViewModel OnPropertyChanged中的更新

OnPropertyChanged在WPF中的作用,越详细越好。谢谢了!!

我们应该在UI线程中调用OnPropertyChanged吗?

WPF:多重绑定不使用 OnPropertyChanged 更新?