【问题标题】:Why there is no shorthand for PropertyChanged in MVVM Light为什么 MVVM Light 中没有 PropertyChanged 的​​简写
【发布时间】:2010-12-29 22:15:40
【问题描述】:

每次我们在 setter 中调用 PropertyChanged 时,MVVM Light 中都没有简写,类似于 flex [Bindable]:

[PropertyChanged]
public bool IsEditable { .... }

为什么每次都要写PropertyChanged("IsEditable"),容易出错,哪里可以默认。

【问题讨论】:

    标签: .net mvvm mvvm-light


    【解决方案1】:

    我决定不将其添加到 MVVM Light,因为解决方案涉及反射(减慢性能)或 IL 编织(这是“魔术”,因此违反了 MVVM Light 的原则,即轻且简单易懂。

    为了“对抗”你提到的问题,我在 MVVM Light 中有三个工具:

    • 代码 sn-p 自动创建“可绑定”属性。只需键入 mvvminpc,然后展开 sn-p。这是避免编写代码的一种简单方法。
    • “魔术字符串”在 VM 类上被声明为公共 const 字符串。这样可以避免拼写错误。
    • 在调试时,ViewModelBase 类会在调用 RaisePropertyChange 时自动检查属性名称是否存在于 VM 类中。这可以在开发游戏的早期发现拼写错误。

    有了这三个工具,我的评估是不需要其他机制。但是,根据大众的需求,我将使用 lambda 表达式向 RaisePropertyChanged 添加一种方法(例如 RaisePropertyChanged(vm => vm.MyProperty))。当然,如果您不想获得这意味着的性能命中,这将是可选的。

    此外,我今年一直在与有影响力的人(包括 Anders Heljsberg)交谈,并强调如果能在框架中(甚至在语言中)实现这一点会很好。这将是最令人满意的解决方案(因为 MSFT 可以对此进行性能优化),但这显然需要时间(如果有的话)。

    干杯, 洛朗

    【讨论】:

      【解决方案2】:

      您可以创建strongly typed INotifyPropertyChanged 行为。这将允许您执行类似...

      RaiseChanged(() => this.PropertyName);
      

      【讨论】:

      • 如果可行,可以将其添加为代码 sn-p,并且对我有用,谢谢 Aaron。我会试一试的。
      【解决方案3】:

      如果不重写 IL 以插入 PropertyChanged 调用,则无法完成此操作。 (或者使用极慢的代理,并在运行时构建继承的类型)

      您正在寻找PostSharp

      您还可以创建一个引发事件的代码 sn-p:

      <?xml version="1.0" encoding="utf-8" ?>
      <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
          <CodeSnippet Format="1.0.0">
              <Header>
                  <Title>Property With Change Event</Title>
                  <Shortcut>propc</Shortcut>
                  <Description>Code snippet for property that calls OnPropertyChanged and XML description</Description>
                  <Author>SLaks</Author>
                  <SnippetTypes>
                      <SnippetType>Expansion</SnippetType>
                  </SnippetTypes>
              </Header>
              <Snippet>
                  <Declarations>
                      <Literal>
                          <ID>type</ID>
                          <ToolTip>Property type</ToolTip>
                          <Default>string</Default>
                      </Literal>
                      <Literal>
                          <ID>property</ID>
                          <ToolTip>Property name</ToolTip>
                          <Default>MyProperty</Default>
                      </Literal>
                      <Literal>
                          <ID>field</ID>
                          <ToolTip>Backing field name</ToolTip>
                          <Default>myProperty</Default>
                      </Literal>
                      <Literal>
                          <ID>desc</ID>
                          <ToolTip>The description of this property</ToolTip>
                          <Default>...</Default>
                      </Literal>
                  </Declarations>
                  <Code Language="csharp"><![CDATA[$type$ $field$;
                  ///<summary>Gets or sets $desc$.</summary>
                  public $type$ $property$ {
                      get { return $field$; }
                      set { $field$ = value; OnPropertyChanged("$property$"); }
                  }
                  $end$]]></Code>
              </Snippet>
          </CodeSnippet>
      </CodeSnippets>
      

      【讨论】:

      • @NSingla:这需要二进制重写器。把它放在一个 MVVM 框架(它只是一个引用的库)中是没有意义的
      • 哦! PostSharp 的任何开源替代品?
      • 该属性仍然缺乏 OP 作为关注点提出的强类型行为,因为它确实容易出错
      【解决方案4】:

      无论好坏,都不可能按照您建议的方式使用编译时属性实现自动属性更改通知。但是,在调试版本中运行时,在 MVVM Light 中,将验证您的 PropertyChanged 调用以确保它们对应于真实属性,这意味着在不更改字符串的情况下重构属性名称在调试构建。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 2011-04-20
        • 2011-10-06
        • 2016-12-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多