【问题标题】:Is the 'Self' construct useful in Silverlight/MVVM?'Self' 构造在 Silverlight/MVVM 中有用吗?
【发布时间】:2023-03-16 18:45:01
【问题描述】:

我继承了一个整体代码质量可疑的 Silverlight 项目,我不确定是否应该触及它:

public SomeClass Self
{
    get
    {
        return this;
    }
}

在 XAML Bindings 中使用,带有参数,有时像这样复杂:

Visibility="{Binding Self, ConverterParameter=!, Converter={StaticResource SmartAssConverter}}"

并且在 PropertyChanged 通知中使用(MVVM Light):

RaisePropertyChanged("Self");

那么,有什么东西阻止我这样做:

Visibility="{Binding ConverterParameter=!, Converter={StaticResource SmartAssConverter}}"

哪个,我已经测试过,仍然显示得很好?

重新表述我的问题,是否有必要“提高财产改变”迫使这种(恕我直言丑陋的)构造?

编辑:再次改写,是否有更优雅的解决方案来通知绑定控件其目标已更改,还是我应该考虑重新设计转换器?

【问题讨论】:

    标签: silverlight data-binding mvvm mvvm-light valueconverter


    【解决方案1】:

    如果对象(即Self)发生变化怎么办?使用 Self 属性时,您可以利用 INotifyPropertyChanged 接口来告知绑定已更新。如果您删除该属性,那么您将如何更新?

    你可以试试RaisePropertyChanged(string.Empty),但我认为这行不通。

    通常,转换器只会传递他们需要的属性,而不是整个对象。但在 Silverlight 中,没有 MultiBinding,因此您只能使用单个属性。

    您可以将新属性添加到执行与转换器相同的操作的对象中,也可以使用添加该属性的另一个对象包装它。这通常是视图模型的角色。

    【讨论】:

    • 嗯,我想你用“MultiBinding”搞定了。其中一些转换器取决于几个属性。我认为转换器也做了太多事情,所以我认为您对“将其移至 ViewModel”部分也是正确的。
    • 如果你确实想走多绑定路线,我在这里创建了一个 SL 多绑定解决方案:scottlogic.co.uk/blog/colin/2010/05/…
    • 我刚刚重新阅读了一个转换器的代码,不久前我在其中添加了这条评论:'// TODO: (J) replace by property in ViewModel'。我想我还是同意自己的观点:)
    • 使用 '{Binding Self}' 和 '{Binding}' 是一样的——都指向底层视图模型。当视图模型被替换时,被绑定的 UI 元素的数据上下文被改变并且所有的绑定被刷新。如果您想通知视图视图模型的所有属性已更改(或者如果您想强制刷新),请使用RaisePropertyChanged(null)
    • @Obalix - 只有在 DataContext 发生变化时才相同,但情况可能并非如此(如果有问题的对象是根视图模型/数据上下文)。此外,INotifyPropertyChanged 仅通知对象上的某个属性或所有属性已更改,而不是对象本身已更改。所以 INotifyPropertyChanged 不能用于更新 {Binding},其中绑定的对象是触发 PropertyChanged 事件的对象。
    【解决方案2】:

    您显示的代码看起来有点笨拙,但我认为它没有那么糟糕,需要重新编写。你是对的,你可以完全删除路径,这将适用于绑定的一次性评估。然而,令人担忧的部分是代码引发了“Self”的属性更改以重新评估绑定(很棒的黑客......我会记住这一点以备将来使用!)

    这里的正确方法是改变DataContext本身,这实际上是改变'self'并且会导致所有绑定被重新评估。

    就个人而言,我不会在这上面花太长时间,我见过更糟糕的情况!

    【讨论】:

    • 好的,谢谢您的意见!我不太担心更新这个项目(我希望会完全重新完成,因为味道比这更糟糕),而是想为我将要编写的新代码找到“正确”的方法。跨度>
    【解决方案3】:

    我通常实现IChangeTrackingINotifyPropertyChanged接口,然后在默认构造函数中执行以下操作:

    public SomeClass()
    {
        this.PropertyChanged += new PropertyChangedEventHandler(OnNotifiedOfPropertyChanged);
    }
    
    private void OnNotifiedOfPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e != null && !String.Equals(e.PropertyName, "IsChanged", StringComparison.Ordinal))
        {
            this.IsChanged = true;
        }
    }
    

    IsChanged 属性会引发属性更改通知,因此您可以绑定到IsChanged,以便在修改类时收到通知,而无需将类本身公开为“Self”属性。

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      相关资源
      最近更新 更多