【问题标题】:Updating WPF DataGrid without firing OnPropertyChanged在不触发 OnPropertyChanged 的​​情况下更新 WPF DataGrid
【发布时间】: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 中包含他们的姓名,否则其他评论者不会
  • 我会避免在每次属性更改时调用外部服务,因为它会导致客户端和服务之间的“闲聊”交互。我可以看到这种方法的一些其他问题:如果客户端和服务之间的延迟增加,您将看到来自先前更改的通知覆盖最新更改。

标签: c# wpf wcf data-binding inotifypropertychanged


【解决方案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,然后触发消息到服务器。不知道怎么区分。
猜你喜欢
  • 2012-06-24
  • 2012-05-28
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 2019-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多