在哪里放置依赖属性?

时间:2012-09-03 22:50:52

标签: c# wpf mvvm dependency-properties

我对使用MVVM模式构建WPF应用程序时放置依赖项属性的位置感到困惑。它是在模型还是ViewModel中?

修改

在查看早期答案后(感谢那些),我发现我仍然感到困惑,所以我提供了更多细节,以帮助别人向我解释。

我有一个名为Station的课程。测量员和土木工程师使用它来表示沿路的长度。在大多数情况下,一个站只是一个双,但它有一些装饰。首先,格式不同。当距离大于100英尺时,我们添加一个+符号作为格式化它的另一种方式。所以在1234.56英尺的路上我们可能有12号站+ 34.56站。 (我会跳过其他装饰品,因为这个装饰对我来说已经足够了。)

因此,特殊格式的逻辑存在于Station中,这是Model中的一个类。我希望View中的TextBox获取1234.56的用户输入并将其强制转换为文本值“12 + 34.56”。所以我想让TextBox为用户提供模型中的值的访问权限,因此它需要是一个依赖属性。 (这是正确的,不是吗?)但是强制/解析/理解如何在TextBox和Station之间来回切换的业务逻辑应该存在于Station类中。 (右?)

此外,我稍后会想让用户通过点击道路的图形绘图来设置站值,包括在鼠标移动时动态更新值并在发出数据点时锁定值。 (现在你明白为什么我试着保持这个简短。)

因此,这不是我想要创建依赖属性的东西,尤其是动态数据点可能会在以后涉及吗?如果没有,如何使用MVVM将文本框项目挂接到工作站? (在问我的问题之前,我确实研究了很多,但没有成功。)

2 个答案:

答案 0 :(得分:3)

通常,您不会在ViewModel或Model中使用依赖项属性。

依赖项属性仅适用于与View相关的功能。您将View的DP绑定到ViewModel,而不是实现INotifyPropertyChanged

将DP放入ViewModel或模型本身实际上会违反MVVM的主要目标之一,因为这会将用户界面技术(WPF)耦合到您的模型或特定于应用程序的类型。

答案 1 :(得分:2)

使用MVVM,您更喜欢INotifyPropertyChanged属性而不是DependencyProperties。

您的Station类应使用INotifyPropertyChanged实现该属性。您的TextBox绑定应使用转换器以您希望的格式显示和读取值。

public class Station : INotifyPropertyChanged
{
    private decimal _value;
    public decimal Value
    {
        get { return _value; }
        set
        {
            if (_value == value) return;

            _value = value;
            NotifyPropertyChanged("Value");
        }
    }
    /* INotifyPropertyChanged implementation */
}

public class StationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string formattedValue = // Add the plus here
        return formattedValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string numericValue = // Parse the optional '+' out of the value
        decimal stationValue = decimal.Parse(numericValue);
    }
}

XAML:

<UserControl.Resources>
    <StationConverter Key="StationConverter" />
    <TheViewModel Key="TheVM" />
<UserControl.Resources>

<TextBox Text="{Binding Path=Station.Value, Source={StaticResource TheVM}, Converter={StaticResource StationConverter}, Mode=TwoWay}"/>