为什么 MVVM Light 中没有 PropertyChanged 的​​简写

发布于 2024-10-09 23:54:15 字数 212 浏览 2 评论 0原文

MVVM Light中每次我们在setter中调用PropertyChanged时都没有简写,就像在flex [Bindable]中一样:

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

为什么我们每次都要写PropertyChanged(“IsEditable”),它容易出错,可以默认。

Where there is no shorthand in MVVM Light each time we call PropertyChanged in the setter, something like in flex [Bindable]:

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

why do we have to write PropertyChanged("IsEditable") everytime, its error prone, where it can be defaulted.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你的往事 2024-10-16 23:54:15

我决定不将其添加到 MVVM Light 中,因为解决方案涉及反射(这会减慢性能)或 IL 编织(这是“魔法”,因此违背了 MVVM Light 的原则,即轻量且易于理解) 自动

为了“解决”您提到的问题,我在 MVVM Light 中提供了三个工具:

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

,我的评估是不需要其他机制,但是,根据大众的需求,我将添加一种使用 lambda 表达式的 RaisePropertyChanged 方法(例如 RaisePropertyChanged(vm => vm.MyProperty))。 )。当然,如果您不想受到这意味着的性能影响,那么这将是可选的。

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

干杯,
洛朗

I decided against adding this to MVVM Light because the solutions involve either Reflection (which slows down the perf) or IL weaving (which is "magic" and as such goes against the principles of MVVM Light, which is to be light and simple to understand.

To "fight" against the issues you mention, I have three tools in MVVM Light:

  • Code snippet to create a "bindable" property automatically. Simply type mvvminpc and then expand the snippet. It is an easy way to avoid writing the code.
  • The "magic string" is declared as a public const string on the VM class. This way you avoid typos.
  • At debug time, the ViewModelBase class automatically checks if the property name exists on the VM class when RaisePropertyChange is called. This catches typos early in the development game.

With these three tools, it is my evaluation that other mechanisms are not necessary. However, by popular demand, I will add a way to RaisePropertyChanged using a lambda expression (eg RaisePropertyChanged(vm => vm.MyProperty)). This will be, of course, optional if you don't want to have the perf hit that this implies.

Also, I have been talking this year to influencial people (including Anders Heljsberg) and underlined that it would be nice to have this baked in the framework (or even in the language). That would be the most satistying solution (because of the perf optimizations that MSFT could do on that), but that will take time, obviously (if it ever happens).

Cheers,
Laurent

烂柯人 2024-10-16 23:54:15

您可以创建强类型化 INotifyPropertyChanged 行为。这将允许你做类似的事情......

RaiseChanged(() => this.PropertyName);

You can create strongly typed INotifyPropertyChanged behavior. Which would allow you to do something like...

RaiseChanged(() => this.PropertyName);
伤感在游骋 2024-10-16 23:54:15

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

您正在寻找 PostSharp

您还可以创建引发该事件的代码片段:

<?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>

This cannot be done without rewriting the IL to insert PropertyChanged calls. (Or using extremely slow proxies, and building inherited types at runtime)

You're looking for PostSharp.

You could also create a code snippet that raises the event:

<?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>
葬﹪忆之殇 2024-10-16 23:54:15

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

For better or for worse, it's not possible to implement automatic property changed notifications using compile-time attributes in the way you suggest. However, in MVVM Light when running in the debug build, your PropertyChanged calls will be validated to ensure they correspond to real properties, which means refactoring the property name without changing the string will be caught in the debug build.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文