【问题标题】:Powershell - can INotifyPropertyChanged be implemented natively?Powershell - INotifyPropertyChanged 可以本地实现吗?
【发布时间】:2021-03-18 01:54:36
【问题描述】:

有谁知道 INotifyPropertyChanged 接口是否可以在 Powershell 中的对象上本地实现,而无需构建 C# 类并使用 Add-Type 生成新的 .NET 程序集?

我已经在 Google 上搜索了所有我能想到的东西,但无法找到解决方案。

谢谢。

【问题讨论】:

  • 有什么理由要避免使用 C# 和 Add-Type 吗?这对我来说似乎是最好的选择。
  • 主要是我更喜欢 Powershell 与 C# 相比,我发现调试原生 Powershell 脚本与 C# 相比更容易。谢谢。

标签: powershell inotifypropertychanged


【解决方案1】:

我正在尝试使用 Powershell 加载我的 WPF 原型,并且遇到了同样的情况,到目前为止,我发现解决方案非常简单,它包括向 powershell 类添加接口方法,最后要处理的是 CanExecuteChanged事件,通过异常消息它说方法 add_CanExecuteChanged 没有找到,解决方案是简单地添加事件添加器和移除器,对于 e

 class Relay: System.Windows.Input.ICommand {
    [Action[object]]$command;
    
    Relay([Action[object]]$Command){
        $this.command = $Command;
    }

    [void]add_CanExecuteChanged ([System.EventHandler]$handler){}
    [void]remove_CanExecuteChanged ([System.EventHandler]$handler){}

    [bool]CanExecute([object]$arg) {return  $true; }
    [void]Execute ([object]$arg){ $this.command?.Invoke($arg); }
}

对于 INotifyPropertyChanged,情况有所不同,因为它需要 getter 和 setter,并在 setter 上调用 PropertyChanged 处理程序,powershell 中的属性可以作为 C# 中的字段实现,并且在后台 powershell 添加 get_* 和 set_,在 dotnet 中添加属性时,您会发现 get_、set_* 方法代表 getter 和 setter,例如:

class Demo {
    [string]$MyProperty;
}

如果你在结果中的一个实例上执行 Get-Member -Force,你会发现 (get_MyProperty, set_MyProperty) 方法,但是当我尝试这样做时,“例如在 java 中”这些方法不会执行,但是我尝试了没有这些方法的绑定,它工作正常,这是我的实验要点,绑定以两种方式工作:

https://gist.github.com/mouadcherkaoui/7b0f32d9dbefa71102acdbb07299c9bb

这是我修改的源代码,它本身包含很多好的脚本:

https://github.com/SammyKrosoft/PowerShell/blob/master/How-To-Load-WPF-From-XAML.ps1

最好的问候。

【讨论】:

  • Mouad,这很简洁,效果很好(感谢分享),除了如果您通过命令更改绑定到文本框的 Powershell 类字符串属性,例如,文本框值将不更新,因为设置器没有您上面提到的 PropertyChanged 处理程序。如果所有属性都通过 UI 更新,则您的示例可以正常工作,但在某些情况下,似乎仍需要使用具有适当 INotifyPropertyChanged 实现的 C# 类。
  • 我找到了一个关于添加属性的线程,对于 INotifyPropertyChanged,您应该添加 add_PropertyChanged 和 remove_PropertyChanged 方法以及支持 propertyChanged 事件处理程序,然后使用 Add-Member cmdlet 添加类型为 scriptblock 的属性:类 MainVM: INotifyPropertyChanged { [NotifyPropertyChangedEventHandler]$propertyChanged }
  • ` 类 MainVM: INotifyPropertyChanged { [NotifyPropertyChangedEventHandler]$propertyChanged add_PropertyChanged([NotifyPropertyChangedEventHandler]$handler){ $this.propertyChanged += $handler } remove_PropertyChanged([NotifyPropertyChangedEventandler]$handler){ $this.propertyChanged -= $handler } ....... 下一条评论中的属性部分 } `
  • 结合本帖中的解决方案:stackoverflow.com/questions/40977472/…我还没试过!
【解决方案2】:

没有。将 PowerShell 视为 CLI consumer 语言,而不是 producer 语言。也就是说,您可以构造和使用大多数 .NET 类型。但是,PowerShell 本身并没有提供创建新 .NET 类型的工具,更不用说实现接口的类型了。虽然您可以在 PowerShell 中创建自定义对象并使用技巧为这些对象提供 PowerShell 理解的类型名称,但这些技巧不适用于 WPF 等 .NET 库。

【讨论】:

  • 5年后的现在呢?
猜你喜欢
  • 2015-11-10
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2010-10-04
  • 1970-01-01
  • 2014-06-02
相关资源
最近更新 更多