【问题标题】:Propagating property changes in C# across multiple classes [closed]在多个类中传播 C# 中的属性更改 [关闭]
【发布时间】:2020-06-02 20:29:57
【问题描述】:

我正在使用 C#、WPF 和 .NETcore3.1 来设计 GUI。这是我第一次使用 C#,所以我的项目结构可能看起来不寻常或不理想。虽然欢迎提出使代码对 C# 更友好的建议(因为我希望有一些“使用 MVVM”的答案),但这不是我在这里的主要问题。

我最终得到了以下一般结构:

  1. 执行业务逻辑的 DLL 项目,大部分独立于 GUI
  2. 我想用来显示来自 DLL 的信息的 WPF 应用程序

在类方面,这看起来像

  1. DLL 中的一个类(就本问题而言,实际上是一组类)包含实际的业务逻辑,并且出于所有实际目的,您可以假设将异步更改。让我们称之为 BusinessLogicClass
  2. GUI 项目中的一个类,它创建各种表示层,本质上将 BusinessLogicClass 的相关属性重塑为可以使用绑定从 XAML 直接使用的格式。我们称之为 PresentationLayerClass。请注意,这是作为用户控件实现的。
  3. XAML GUI 本身。具体来说,自定义控件的 XAML GUI。

一些伪代码:

// In the DLL

class BusinessLogicClass:
    public Boolean status{ get; set; }

// In the GUI

Using DLLNamespace;

public partial class PresentationLayerClass : UserControl

    private BusinessLogicClass actual;

    public PresentationLayerClass(BusinessLogicClass actual){
        InitializeComponent();
        this.DataContext = this;
        this.actual = actual; 
    }

    public string ConnectionStatus{
        get{
            if (this.actual.status == true) return "LanConnect";
            else return "LanDisconnect";
        }        
    }

    public string StatusColor{ 
        get {
            if (this.actual.status == true) return "Green";
            else return "Red";
        }
    }

// In the XAML
<iconPacks:PackIconMaterial Kind="{Binding ConnectionStatus}" Margin="5" Foreground="{Binding StatusColor}"/>

现在,我知道(虽然还没有弄清楚如何测试它)当 PresentationLayerClass 的属性发生变化时,GUI 将“更新自身”。

我想要的是,对 BusinessLogicClass 的状态属性的异步更改会沿链向上传播到 GUI。

如果有必要,为了简单起见,因为我还没有足够的知识来解释更多,假设一切都在同一个线程上,并且异步更改是由用户在 GUI 本身上触发的。说一个按钮。但是,按钮和此显示器彼此不知道也不一定不知道彼此的任何信息。信息必须通过 DLL,并且 DLL 必须触发对更新的更改。

此外,DLL 不应该被硬编码到 GUI - 我希望能够单独运行 DLL,或者使用 CLI 应用程序或其他 GUI。

我希望 INotifyPropertyChanged 的​​某种组合能够完成这项工作,但我似乎无法弄清楚我将如何设置它。 INotifyPropertyChanged 似乎总是在 GUI 和绑定的上下文中讨论。

我知道 MVVM 应该有助于简化这类事情。虽然我有理由想在这种特殊情况下避免使用 MVVM,但我承认我还没有完全相信 MVVM 通常值得麻烦。我非常反对流行的 MVVM 库建立的明显隐式链接。我无意开始对 MVVM 进行哲学讨论,但任何希望驳斥我这个概念的人都可以把他们的情况搁置一旁——只要你明白 MVVM 不是我在这里提出的问题的主题。

【问题讨论】:

    标签: c# wpf inotifypropertychanged


    【解决方案1】:

    不告诉你你已经知道什么,但只要阅读INotifyPropertyChanged界面,你的很多问题都可能得到解答。


    INotifyPropertyChanged总结

    通常,除非执行检查,否则没有对象知道另一个对象的属性是否已更改。这本质上是事件的目的,当某些事情发生变化时发出警报,这样其他对象就不必一直检查。但是有很多方法可以声明具有各种不同签名的事件。

    INotifyPropertyChanged 提供了一个简单的基本标准,可以用来告诉其他对象什么时候发生了变化,以及什么属性发生了变化。它定义了PropertyChanged 事件,其中包括作为参数的已更改属性的名称。实现INotifyPropertyChanged 的类型负责在属性更改时显式引发PropertyChanged 事件,这通常在每个属性的set 方法中完成。

    WPF 框架旨在支持INotifyPropertyChanged 接口。 WPF 数据绑定检查实现INotifyPropertyChanged 的对象并侦听PropertyChanged 事件。当这个偶数出现时,他们会检查PropertyChangedEventArgs.PropertyName 以查看更改了哪个属性。如果绑定了该属性,WPF 就会知道更新该绑定。

    在 WPF 中,也有dependency properties。它们有很多有用的功能,但最相关的是它们还实现了自己的更改通知,WPF 知道要注意这一点。


    您的实施

    按照您当前定义PresentationLayerClass 的方式,如果ConnectionStatusStatusColor 发生更改,用户界面不会自动更新。这是因为这些属性没有实现为依赖属性或INotifyPropertyChanged 属性。当然,这两个值都取自 BusinessLogicClass,所以让我们从那里开始吧。

    BusinessLogicClass 应该实现INotifyPropertyChanged,并且status 属性在设置时应该引发PropertyChanged 事件。

    除此之外,您还需要为该事件添加一个事件处理程序到PresentationLayerClass。示例:
    private void BusinessLogic_PropertyChanged(object sender, PropertyChangedEventArgs e) 并在构造函数中附加处理程序(public PresentationLayerClass 方法)。

    现在在PresentationLayerClass 级别,在BusinessLogic_PropertyChanged 方法中,您必须检查BusinessLogicClass 的哪个属性已更改(通过使用PropertyChangedEventArgs.PropertyName),然后更新@987654351 的任何属性的值@ 这取决于该更改的属性。根据您决定使用的模式,更新依赖属性会有所不同:

    • PresentationLayerClass 使用依赖属性:您必须为每个依赖的依赖属性显式设置新值。
    • PresentationLayerClass 使用INotifyPropertyChanged:您必须为每个从属属性引发一次PropertyChanged 事件。 (专业提示:使用 nameof 而不是硬编码属性名称)。

    【讨论】:

      猜你喜欢
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 2016-03-18
      • 2016-06-15
      相关资源
      最近更新 更多