Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在使用MVVM时,我应该将WPF特定的代码放在哪里?_C#_Wpf_Mvvm - Fatal编程技术网

C# 在使用MVVM时,我应该将WPF特定的代码放在哪里?

C# 在使用MVVM时,我应该将WPF特定的代码放在哪里?,c#,wpf,mvvm,C#,Wpf,Mvvm,我刚刚开始了解MVVM,但到目前为止,我看到的所有示例都是将视图控件绑定到简单的非WPF特定数据类型,如字符串和int。然而,在我们的应用程序中,我希望能够根据模型中的数字设置按钮的边框笔刷 目前,我将数字转换为ViewModel中的画笔,以仅保留视图XAML,但这是对的吗 我不喜欢将特定于WPF的代码放在ViewModel中,但同样,我也不喜欢将代码放在我的视图面板上 哪种方式最好 谢谢尝试自定义值转换器 仅保留视图XAML的目的是什么?由于可测试性和SoC,保持ViewModel干净是有意义

我刚刚开始了解MVVM,但到目前为止,我看到的所有示例都是将视图控件绑定到简单的非WPF特定数据类型,如字符串和int。然而,在我们的应用程序中,我希望能够根据模型中的数字设置按钮的边框笔刷

目前,我将数字转换为ViewModel中的画笔,以仅保留视图XAML,但这是对的吗

我不喜欢将特定于WPF的代码放在ViewModel中,但同样,我也不喜欢将代码放在我的视图面板上

哪种方式最好


谢谢

尝试自定义值转换器

仅保留视图XAML的目的是什么?由于可测试性和SoC,保持ViewModel干净是有意义的。但是没有代码隐藏

目前,我将数字转换为ViewModel中的画笔,以仅保留视图XAML,但这是对的吗

不,不是真的

理想情况下,应该将WPF依赖项排除在ViewModel之外。这有助于使您的应用程序更易于测试,但也便于将来转换为Silverlight或其他技术

然而,WPF提供了一种用于此确切场景的机制:。制作一个ValueConverter非常容易,它可以将整数、字符串或任何其他类型转换为画笔。显示了使用值转换器将颜色转换为笔刷的示例

从长远来看,这是一个更好的设计。。。“画笔”和其他WPF概念实际上是视图的一部分——它们与您的逻辑无关。您的ViewModel应该按照状态来思考,并且您的视图应该将该状态转换为表示该状态的特定方式

假设您想使用“红色”笔刷显示错误。与ViewModel公开笔刷不同,它应该公开一些基本体(即bool属性),例如
IsInErrorState
。视图应该决定如何表示这一点——是否通过红色画笔、大警告等。。。转换器允许以纯粹的XAML方式实现这一点


在您的情况下,ValueConverter很简单。由于您使用的是数字->画笔(尽管我建议使用自定义枚举而不是int),因此您可以执行以下操作:

[ValueConversion(typeof(int), typeof(SolidColorBrush))]
public class IntToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int option = (int)value;
        switch(option)
        {
            default:
                return Brushes.Black;
            case 1: 
                return Brushes.Red;
            case 2: 
                return Brushes.Green;
           // ...
        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // No need to convert back in this case
        throw new NotImplementedException();
    }
}

再想一想,我同意你的看法。当然,画笔之类的东西不应该暴露出来,因为设计师可能对如何可视化特定状态有不同的想法。这是一个更基本的问题:公开特定于WPF的代码通常意味着您将公开一些可视化的细节,而不是应该可视化的状态的细节。虚拟机与其视图紧密耦合,但职责仍应明确划分。感谢Reed,这正是我所寻找的。我在某个地方读到,最小化视图上的代码落后是一个好主意,以最小化特定于平台的代码(并帮助进行单元测试)。但是接下来的问题是如何避免这个特定于WPF(在我的例子中)的代码污染VM,这就是问题所在。首先建议ValueConverter做得很好,我已经标记了你的答案,但是Reed的答案更详细,所以我给了他一个勾号。谢谢随着应用程序的增长,通常不可能将codebehind保持为空。像处理焦点和定制一些控件行为这样的iUse更多地与设计相关,而不是与模型相关,因此代码隐藏对它们来说是很自然的。好吧,这很有趣,我想在使用MVVM时,我永远不能在我的视图中隐藏任何代码,但知道这一点让人放心,至少你认为这不是必要的,甚至是可能的。再次感谢。