0

好吧,这里的一些聪明人告诉我在操作 UI 项时应该使用绑定。好吧,我对这个有约束力的话题有了一点了解,但是有一件奇怪的事情一直在折磨我。让我们举个例子,这样我就可以更好地描述我的问题。

xml代码:

<TextBox x:Name="MyTextBox" 
                 Text="Text" 
                 Foreground="{Binding Brush1, Mode=OneWay}"/>

c#代码:

public class MyColors : INotifyPropertyChanged
{
    private SolidColorBrush _Brush1;

    // Declare the PropertyChanged event.
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the property that will be the source of the binding.
    public SolidColorBrush Brush1
    {
        get { return _Brush1; }
        set
        {
            _Brush1 = value;
            // Call NotifyPropertyChanged when the source property 
            // is updated.
            NotifyPropertyChanged("Brush1");
        }
    }


    // NotifyPropertyChanged will raise the PropertyChanged event, 
    // passing the source property that is being updated.
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

现在要更改前景的颜色,我可以简单地用代码编写:

MyColors textcolor = new MyColors();

        // Brush1 is set to be a SolidColorBrush with the value Red.
        textcolor.Brush1 = new SolidColorBrush(Colors.Red);

        // Set the DataContext of the TextBox MyTextBox.
       // MyTextBox.DataContext = textcolor;
        MyTextBox.Foreground = new SolidColorBrush(Colors.Blue);

呸,我们终于明白了。现在让我们转到我使用的第二个解决方案。

xml:

<TextBox x:Name="MyTextBox"/>

c#: MyTextBox.Foreground = new SolidColorBrush(Colors.Red);

哇,同样的效果:o 所以现在我的问题是。

除了这件事之外,还有什么命令给了我?Cus 在这一点上我没有看到结果有太大的不同,期望第一个示例占用更多空间并且实现了偶数,而第二个示例占用了 2 行。谁能给我一个很好的例子,他们可以派上用场,因为 msdn 的例子没有给我一个明确的答案。

4

2 回答 2

2

第一种方法(使用 MVVM 设计模式)将您的视图模型与视图分离,从而允许可测试性和在更短的时间内迁移到其他平台的可能性。

第二种方法很简单,但它是紧耦合的。阅读 MVVM 设计模式以全面了解其优势。

于 2013-03-24T07:54:45.937 回答
0

首先要做的事情...在您的问题中,您注释掉了设置 MyTextBox.DataContext 的行,因此您当时甚至没有使用绑定。然后在下一行中,您将值直接设置为 Blue,这意味着您刚刚键入的所有其他内容甚至都没有被使用。我不知道你为什么这样做,但这有点不重要。可能只是一个错字,但我不会编辑它,因为我不确定你的意图。

如前所述,进入问题的“实质”,您做事的第一种方式遵循 MVVM 或 Model-View-ViewModel 模式。模型是数据,在这种情况下是画笔。View 是 TextBox,而 ViewModel 就是您所说的 MyColors。ViewModel 实现了 IPropertyChanged,因此它可以为侦听器(例如绑定)发出更改通知以进行侦听。

使用 MVVM 而不是在第二种情况下(您只需在代码隐藏中直接设置值)进行设计的原因与代码的关注点分离有关。具体来说,应用程序的逻辑及其业务规则与 UI 的逻辑是分开的。

例如,您的业务逻辑可能会说“错误文本需要为红色”,因此您可以在 ViewModel 上公开一个名为 ErrorTextBrush 的属性。您不需要考虑 TextBox 的名称是什么,甚至根本不需要考虑它是否出现在屏幕上。您已将业务关注点与 UI 关注点分开。

同样,开发 UI 的人不需要考虑与业务逻辑相关的任何事情。他们只需要知道他们在屏幕上定义一个 TextBox 作为错误文本的占位符,因此他们只需将 ErrorTextBox.Foreground 绑定到 ErrorTextBrush,现在 UI 遵循业务逻辑的要求。

实际上,人们可以(而且您应该)更进一步,并在 XAML 中定义 ErrorTextBrush,因为它与视图相关,而不是与业务逻辑相关。然后在 ViewModel 中,您将拥有 HasError 之类的属性,并且您将在 XAML 中设置触发器或绑定,说明如果出现错误则使用该错误画笔,否则使用标准画笔。

在这种情况下,业务逻辑甚至不必知道文本是红色的。这完全由 UI 决定。相反,UI 根本不需要知道是什么导致了错误。它只需要知道存在错误,因此它需要向用户显示反映该错误的视觉效果。

同样如上所述,ViewModel 只是一个常规类,而不是一个 UI,这使得进行单元测试变得更加容易。例如,使用上面的示例进行测试,您所要做的就是实例化 ViewModel,设置任何触发错误的条件,然后测试 HasError 属性是否被触发。您可以在没有任何 UI 的情况下完成所有这些操作。

这使开发人员可以处理应用程序的逻辑,而设计人员可以在很少交互的情况下处理 UI。他们几乎只需要交换 UI 需要了解的内容即可。

于 2013-03-24T08:22:48.637 回答