WPF MVVM:ResourceDictionary的配置约定?

Jef*_*ght 6 wpf mvvm


更新

在StackOverflow的维基精神中,这是一个更新:

我在下面抨击了Joe White的IValueConverter建议.它就像一个魅力.

我写了一个"快速入门"的例子,它使用一些廉价的字符串替换自动映射ViewModels-> Views.如果未找到代表ViewModel的View,则默认为"Under Construction"页面.我正在配音这种方法"WPF MVVM White",因为这是Joe White的想法.这是一些截图.

第一个图像是"[SomeControlName] ViewModel"具有相应的"[SomeControlName] View",基于纯命名约定.第二种情况是ModelView没有任何视图来表示它.没有更多的ResourceDictionaries具有长ViewModel来查看映射.现在它是纯粹的命名约定.

Wpf Mvvm White

我在这里发布了一个项目下载: Mvvm.White.Quickstart.zip


原帖

我在周末阅读了Josh Smith 关于WPF MVVM 的精彩MSDN文章.它注定是一个邪教经典.

我花了一些时间来讨论要求WPF呈现ViewModel的魔力.

这就像是说"这是一个类,WPF.去弄清楚用哪个UI来呈现它."

对于那些错过这种魔力的人来说,WPF可以通过在ResourceDictionary映射中查找View for ModelView并拉出相应的View来实现这一点.(向下滚动到图10提供视图).

立即跳出来的第一件事是,已经有一个强大的命名约定:

classNameView  ("View" suffix)
classNameViewModel ("ViewModel" suffix)
Run Code Online (Sandbox Code Playgroud)

我的问题是:

由于ResourceDictionary可以以编程方式进行操作,我想知道是否有人设法使用Regex.将整个事情放弃,因此查找是自动的,并且任何新的View/ViewModel都会因其命名约定而得到解决?

[编辑]我想象的是对ResourceDictionary的钩子/拦截.

...还考虑启动时使用interop拉出的方法*View$*ViewModel$类名来在代码中构建DataTemplate字典:

//build list
foreach ....
    String.Format("<DataTemplate DataType=\"{x:Type vm:{0} }\"><v:{1} /></DataTemplate>", ...)
Run Code Online (Sandbox Code Playgroud)

Joe*_*ite 17

而不是编写代码以显式添加到ResourceDictionary的东西,如何只是按需生成正确的视图?您可以使用ValueConverter执行此操作.

您的资源如下所示:

<Views:ConventionOverConfigurationConverter x:Key="MyConverter"/>
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}">
    <ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

您仍然需要DataTemplate资源,但只要您的ViewModel都具有公共基类,您只需要一个DataTemplate来处理所有这些资源.

然后定义值转换器类:

public class ConventionOverConfigurationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        // value is the ViewModel. Based on its GetType(), build a string
        // with the namespace-qualified name of the view class, then:
        return Activator.CreateInstance(Type.GetType(viewName));
    }
    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要做的就是在Convert中编写逻辑,这取决于您的Views和ViewModel是否在同一名称空间中.