只有我觉得WPF是数据绑定和自定义IValueConverter的混乱吗?

7
说实话,每次我想让我的UI元素彼此交流时,都会编写一个新的自定义IValueConverter :(。请有人告诉我我做错了,好吗!
例如: - 我想让按钮仅在我的文本框包含有效URI时启用。太好了,是时候编写UriIsValidConverter了! - 哦糟糕,我还想在处理某些内容时禁用它。我猜现在需要编写UriIsValidAndBoolIsFalseMultiConverter! - 我想在列表框中显示特定目录(由文本框指定)中的文件列表。我猜我需要一个DirectoryPathToFileList转换器! - 哦,嘿,我想为列表视图中的每个文件添加图标。是时候使用FileInfoToBitmap转换器了! - 如果我的状态字符串包含“Error”,则我希望我的状态为红色,否则为绿色。耶,我可以编写一个StatusStringToSolidColorBrushConverter!
我真的认为这并不比旧的Windows Forms方法手动使用TextChanged事件(或其他事件)连接所有内容要好多少。我想这仍然是一种选择。也许这就是人们实际上所做的,而我试图过于努力使一切符合数据绑定范例?
所以,请告诉我这是否就是WPF编程的方式,或者如果我做错了,那我应该做什么。

Closer可能是在回应这个人问题中的挫败感。你现在的做法似乎非常令人沮丧。这就是为什么你需要了解MVVM,它可以完全消除沮丧感。 - user1228
3个回答

10

你的方法是完全有效的(虽然我会使用多绑定来代替这样一个专门的转换器),但是通过将所有逻辑放入XAML中,你正在产生非常高的耦合度,这会导致应用程序外观和行为之间的紧密联系,因此你可能需要研究MVVM模式来将它们分开。

在MVVM模式下,你的XAML(视图)只包含针对ViewModel的简单数据绑定,ViewModel处理所有逻辑并通过INotifyPropertyChanged接口更新视图。你第三个例子的代码可能如下所示:

public class DirectoryManagerViewModel : INotifyPropertyChanged
{
    private string _directory;

    public string Directory
    {
        get { reutrn _directory; }
        set
        {
            if (_directory != value)
            {
                 _directory = value;
                 OnPropertyChanged("Directory");
                 if (IsValidDirectory(value))
                 {
                     PopulateFiles();
                 }
            }
        }
    }

    public ObservableCollection<FileViewModel> Files { get; private set; }

    private bool IsValidDirectory(string directory)
    {
          //return if the directory exists etc.
    }

    private bool PopulateFiles()
    {
         //Populate Files with files in directory
    }
}

其中FileViewModel是另一个包含文件名称和图标的视图模型。

这种方法的优点在于,可以将ViewModel与其他视图和其他技术(如ASP.NET或Winforms)一起重用,因此您不会被锁定到WPF堆栈中。(如果您在有设计师负责外观和开发人员负责行为的环境中工作,这有助于定义这些边界)

不过,归根结底,这个逻辑确实需要放在某个地方,虽然有更好和更差的架构应用程序的方式,但你仍然需要编写代码将字符串转换为一系列的文件名和图标。


MVVM是这个人的问题的答案。验证逻辑和打开关闭等所有操作都在ViewModel中进行。 - user1228
谢谢你,还有其他回答者!我在刚开始时看了MVVM,但是被它的复杂性吓到了。但是你的例子真的很有帮助,让我看到了它的基础,并说服我再试一次。你提到代码必须要去某个地方的观点也很好。 - Domenic

5

首先,您可能需要阅读有关Model-View-ViewModel pattern(MVVM)的内容。Josh Smith最近在MSDN杂志上发表了一篇很棒的文章。MVVM和WPF完美地结合在一起。如果做得好,您将不会如此频繁地需要IValueConverters。现在的方式会导致可视化和应用程序操作之间非常紧密的耦合。MVVM旨在解除这些元素之间的耦合。

在这种情况下,您的视图模型将为您跟踪状态。如果您视图模型中某个ICommandCanExecute 方法返回 true,则您的按钮将启用。同样的概念可以在处理某些内容时禁用该按钮。
想要显示特定目录中文件列表?使用一个DirectoryViewModel视图模型来通过绑定向视图提供文件列表。文件的显示可以使用在XAML中指定的DataTemplate指定,无需代码后台。同样的概念可以用于提供图标以在模板中指定其显示。
如果状态信息包含“Error”,则您希望状态为红色,否则为绿色?让视图模型处理确定状态,并让视图绑定到该状态,现在您只需要一个IStateConverter将状态适当地转换为红色或绿色(这是在MVVM上下文中处理此问题的众多方式之一)。
养成将数据和状态与视图分离的习惯,您的应用程序将松散耦合,更易于设计和维护,也更易于测试。

5

不知道你是否犯了错误,只是让它变得比实际需要的更难了!

我使用MVVM模式,所以你编写客户端转换器时,我在视图模型中提供一个可绑定属性,告诉视图该怎么做。例如:

  1. 要显示文件列表,我提供包含该列表的集合。
  2. 如果我想要图标,则该集合中的对象具有一个图标属性。
  3. 如果我想要状态为红色或绿色,则提供StatusColorbrush属性。

通过将此逻辑移入视图模型中,我获得:

  1. 更简单的Xaml。
  2. 可以在没有视图的情况下测试我的视图逻辑。

这种方法利用了WPF的一个强项,即其绑定功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接