ViewModel 中的可绑定字段 [重复]

Posted

技术标签:

【中文标题】ViewModel 中的可绑定字段 [重复]【英文标题】:Bindable field in ViewModel [duplicate] 【发布时间】:2013-03-27 20:38:36 【问题描述】:

在 ViewModel 中通常有很多这样的

private string someField;
public string SomeField

    get 
    
        return someField;   
    
    set
    
        someField = value;
        NotifyOfPropertyChanged(() => SomeField);
    

有没有办法获得这种结构的简短版本,甚至是Bindable

所以你只需要写这样的东西:

public Bindable<string> SomeField;

也许有一个应该为NotifyPropertyChanged触发的动作...

【问题讨论】:

没有重复,因为在可能的重复中没有回答问题。 绑定只适用于公共属性。这就是 wpf 绑定的工作原理。如此简短的回答:不。你必须绑定到属性 【参考方案1】:

我想您可以创建自己的类来维护一个值并针对您可以创建的包含类引发INotifyPropertyChanged

public Bindable<string> SomeField = new Bindable<string>("test", this);

然后绑定SomeField 将访问包含的值并设置它会导致INotifyPropertyChanged 针对this 引发

您需要使用一些隐式转换运算符才能让绑定系统将您的Bindable&lt;T&gt; 视为T 的来源和放置T 的地方

见:http://msdn.microsoft.com/en-us/library/85w54y0a.aspx

以下内容可能就足够了:

public class Bindable<T>

    private T _value;
    private PropertyChangedEventHandler _notifyHandler;
    private INotifyPropertyChanged _notifyTarget;
    private string _name;

    public Bindable(PropertyChangedEventHandler notifyHandler, INotifyPropertyChanged notifyTarget, string name, T value = default(T), bool trigger = false)
    
        _value = value;
        _name = name;
        _notifyHandler = notifyHandler;
        _notifyTarget = notifyTarget;

        if (trigger)
        
            _notifyHandler(_notifyTarget, new PropertyChangedEventArgs(_name));
        
    

    public implicit operator T(Bindable<T> bindable)
    
        return bindable._value;
    

    public implicit operator Bindable<T>(T value)
    
        return new Bindable<T>(_notifyHandler, _notifyTarget, _name, value, true);
    

上面的代码很粗糙,毫无疑问可以创建一个更好的版本,但它应该为你指明你需要去的方向。


在对我提出的解决方案进行进一步调查时,我发现由于从 TBindable&lt;T&gt; 的隐式转换,为了记住目标和其他细节,开始工作会有问题,我敢肯定这种解决方案包含足够多的想法来产生可行的解决方案。

【讨论】:

我认为绑定系统甚至应该只看到T...否则绑定时会出现一些问题,例如字符串到 TextBox.Text 或类似 克林特,这是一个很酷的想法,但是您是否测试过它确实可以与数据绑定一起使用?我有疑问。但是有一个简单的解决方法:添加一个属性Value,它封装了_value,并且只是一个简单的实现通知属性。绑定将不得不使用这个属性。但是,与 Caliburn.Micro 结合使用可能会出现问题。 @DanielHilgarth 我没有直接测试过这段代码,不,我之前做过类似的事情,因为我很懒,INotifyPropertyChanged 一次又一次地实施可能真的很痛苦,即使代码不完整,原则也是合理的:P 但是同意,一些框架本身进行怪异的反射可能会有问题。 @Clint:但即使没有 CM,这也有点问题。假设将Bindable&lt;int&gt; 绑定到TextBlock.Text。我认为它不会使用转换运算符,因为Textstring,而不是int。文本块内的文本将是Bindable.ToString()返回的字符串。 @Clint:是的,我确实同意这一点。我只是认为指出此解决方案可能遇到的问题很重要,因此可以避免这些问题。正如我所说,我认为这是一个很酷的解决方案。【参考方案2】:

存在自动属性,可以用作没有逻辑的属性的快捷方式。

以下两个属性是等价的:

private string someField;
public string SomeField

    get  return someField; 
    set  someField = value; 


public string SomeField  get; set; 

但是,没有内置方法可以在其中引入更改通知。

但如果您想投入时间和/或金钱,有一些方法可以让自动属性通知更改:

    使用像 PostSharp 这样的 AOP 框架。它将在编译后步骤中注入此功能:http://www.postsharp.net/model/inotifypropertychanged。这种方法的缺点是 PostSharp 不是免费的。 使用动态创建的代理类。在运行时,您可以创建一个派生自实际 ViewModel 的类,并使用更改通知覆盖每个属性。这种方法的缺点是您需要使用该代理而不是您的类,并且您的所有属性都需要是虚拟的。

【讨论】:

Autoproperty 无法回答我的问题... @MareInfinitus:你为什么这么说?单独的汽车属性确实不是解决方案,但这不是我回答的核心。 因为事实上,自动属性与我的问题的核心无关。 @MareInfinitus:您可能想真正阅读我的答案。您问题的核心是:如何制作 UI 可以绑定的短属性?我的回答回答了这个问题。 @MareInfinitus:这是不正确的。我不仅说它是如何实现的,我什至给你两种不同的实现方式:(1)使用 PostSharp(2)使用动态代理。

以上是关于ViewModel 中的可绑定字段 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

WPF 在 MVVM 模式下实现窗口后台代码与ViewModel交互

在 ViewModel 中更新其绑定后,按钮未启用 [重复]

SwiftUI 文本字段中的可选链接绑定值

proto 3 中的可选(重复)字段

带有 IEnumerable<child> 成员的 ViewModel 在 POST 上未正确绑定 [重复]

WPF中的绑定祖先元素[重复]