使大型模型可观察

时间:2015-04-09 21:01:08

标签: c# wpf

我参与了我的第二个WPF项目并遇到了一个不舒服的情况。这是我的模特:

public class Layout
{
    public string Name { get; set; }
    public Motor Motor { get; set; }
}

public class Motor
{
    public string Property1 { get; set; }
    ...
    public string Property150 { get; set; }
}

这是我的MainViewModel:

public class MainViewModel : ViewModelBase
{
    public Motor Motor {get; set;}
    ...
}

好的,我已将电机类的所有150个属性绑定到文本框:

<TextBox Text="{Binding Layout.Motor.Property1}"/>

问题1)如果我想在用户更改其中一个时触发动作,我是否必须实施150次?

    private string property1 { get; set; }
    public string Property1
    {
        get { return property1; }
        set
        {
            property1 = value;
            RaisePropertyChanged(() => Property1);
        }
    }

问题2)我是否必须在MainViewModel中实现这一点,在模型&#34; Motor&#34;或者我需要一个&#34; MotorViewModel&#34;?任何这些都意味着大量的复制和粘贴以及完全无用的编码......

感谢您提供任何帮助和反馈!

2 个答案:

答案 0 :(得分:2)

首先,RaisePropertyChanged实际上是 UI ,在代码更改项目时通知它。当然,您也可以手动收听,但通常不会。

您通常也不会使用自动属性作为支持字段,但这可能是由于PropertyChanged实施所致。

现在已经不在了:

是的,你需要实现它,或类似的东西,允许PropertyChanged被提升150次。现在,人们想知道为什么你在地球上有150个属性,所以你可能想先重新考虑一下这个设计。但如果你真的需要它们,那么是的,复制粘贴是你的未来。考虑编写代码片段以使其更快。

要回答您的其他问题,您可以轻松地将其放入&#34;型号&#34;对象,只要该对象可以充当DTO。换句话说,它实际上并没有以某种方式与模型相关联(例如,具有模型功能),但可以在层之间浮动。你甚至可以把INPC放在数据合同上,它不会伤害任何东西。

还有一件事需要考虑,如果您只想在 motor 更改时通知UI而不是其各自的属性,您只需通知Motor属性和所有绑定将更新。

答案 1 :(得分:1)

动态救援!

public class DynamicDictionary : DynamicObject, INotifyPropertyChanged
{
    private readonly Dictionary<string, object> dictionary;

    public DynamicDictionary(Dictionary<string, object> dictionary)
    {
        this.dictionary = dictionary;
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        // magic!
        OnPropertyChanged(binder.Name);
        return true;
    }

    #region INPC implementation
    // SNIP!  I ain't writing all that junk out
    #endregion
}

(大部分代码都来自this answer

绑定识别实现IDynamicMetaObjectProvider的类型,就像DynamicObject一样,并且知道如何使用它们。试试吧,看看。