【问题标题】:MVVM Properties in ViewModel?ViewModel 中的 MVVM 属性?
【发布时间】:2013-05-27 14:04:51
【问题描述】:

我有一个绑定到 ViewModel 的视图

DataContext="{Binding MyViewModel, Source={StaticResource Locator}}">

文本框...绑定到 ViewModel 中的属性:

<TextBox Text="{Binding MyValue, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayValue}"/>

ViewModel 中的属性:

public MyViewModel()
{
    DisplayValue = "0€";
    MyValue = "0";
}

private string _myvalue;
public string MyValue
{
    get
    {
        return _myvalue;
    }
    set
    {
        _myvalue = value;
        ChangeValue();
        RaisePropertyChanged(() => MyValue);
    }
}

private string _displayvalue;
public string DisplayValue
{
    get
    {
        return _displayvalue;
    }
    set
    {
        _displayvalue = value;
        RaisePropertyChanged(() => DisplayValue);
    }
}

private void ChangeValue()
{
//do something here and change the values of the property, e.g.:
DisplayValue = MyValue + "€";
}

这只是一个片段。我通常在 VIEWMODEL 中有大约 50 个属性,所有方法也在 ViewModel 中(意味着 RelayCommands 和方法,将在大约 50% 的属性的设置器中调用)。 如您所见,我没有使用任何模型。这是使用 MVVM 的正常方式还是应该创建一个新类并将所有属性/方法放在新类(模型)中?...但是我应该如何将视图中的元素与属性中的属性绑定Model,viewsDataContext什么时候绑定到ViewModel?

编辑:说清楚。 我有一个 TextBox,TextBox 绑定到 ViewModel 中的一个属性。这是使用 MVVM 的正确方法吗?我应该只在我有一个列表(例如 ComboBox)时使用 Model-Class,还是在我有多个 TextBox(在我看来这有点愚蠢和不必要)时才使用?

【问题讨论】:

  • 好吧,这可能是一个愚蠢的评论,但你测试过这段代码吗?据我所知,当您设置 MyValue 时,您会引发 PropertyChanged 事件,然后调用 ChangeValue() 方法,该方法将设置 MyValue 属性,该属性将引发 PropertyChanged 事件,该事件将调用 ChangeValue() 方法,该方法将设置MyValue 属性...等等。除非 MyValue += "€" 不使用 Setter,但我对此表示严重怀疑。似乎就像一个很好的旧无限循环/内存泄漏。但同样,我没有自己测试过,所以我可能是错的;)
  • 是的,你是对的......愚蠢的例子,要改变(编辑)它

标签: c# xaml mvvm binding


【解决方案1】:

我希望我能理解你想要做什么。我的解决方案包括我在 MVVM 模式中使用的 DependencyProperty,而不是 INotifyPropertyChanged。

假设您有一个模型,其中包含一个属性:

public class SymbolStatsModel
{
    public string Symbol
    {
        get
        {
            return this._symbol;
        }
        set
        {
            this._symbol = value;
        }
    }
}

那么对应的ViewModel就会是这个样子。声明一个属性和一个依赖属性:

public string Symbol
{
    get
    {
        return (string)GetValue(SymbolProperty);
    }
    set
    {
        SetValue(SymbolProperty, value);
    }
}

public static readonly DependencyProperty SymbolProperty =
    DependencyProperty.Register
    (
        "Symbol",
        typeof(string),
        typeof(SymbolStatsViewModel),
        new FrameworkPropertyMetadata
        (
            string.Empty
        )
    );

并且还要在ViewModel中创建Model类的属性(SymStatsModel):

public SymbolStatsModel SymbolStatsModel
{
    get
    {
        return new SymbolStatsModel(Symbol);
    }
    set
    { 
        this.Symbol = value.Symbol;
    }
}

这样,您分配给 ViewModel 符号属性的值将被分配给模型属性。此外,您可以通过访问 ViewModel 中存在的 Model 的属性,直接从 View 访问 Model 的属性。

这可能有点难以理解,但这确实是让视图与模型通信的方式。另一方面,您可以像我在解决方案中提到的那样指定模型的属性,同时使用 INotifyPropertyChanged。我猜有点不成熟,但你考虑了一下。

【讨论】:

  • 感谢您的回答。我会尝试看看会发生什么,但这并不是我真正想要的答案。我想知道我是否正确使用了 MVVM。我见过一些 MVVM 示例,其中用户将 DataContext 绑定到 ViewModel,但也可以将视图中的元素与模型中的元素绑定(我不知道他们是如何做到的......)。所以我真正想知道的是,将 View 绑定到 ViewModel 并在 ViewModel 中创建所有属性是否“可以”,还是我必须创建一个模型? (仅供参考,我使用 ~95% 的文本框或文本块和 5% 的组合框)
  • 请不要在不需要的时候使用依赖属性。在这种情况下,NotifyPropertyChanged 是要走的路,而不是依赖属性。
【解决方案2】:

“分而治之”应该有助于您的可维护性

  • 尝试在您的 UI、逻辑组、重复部分中找到边界。
  • 把它们排除在外
  • 您可以随时重置 DataContext,或者使用更复杂的绑定路径,例如 MyVm.SubVm.Property

【讨论】:

    猜你喜欢
    • 2013-06-13
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多