WPF MVVM:ResourceDictionary的配置约定? [英] WPF MVVM: Convention over Configuration for ResourceDictionary?

查看:153
本文介绍了WPF MVVM:ResourceDictionary的配置约定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新

按照StackOverflow的Wiki精神,这是一个更新:

In the wiki spirit of StackOverflow, here's an update:

我在下面加注了乔·怀特(Joe White)的IValueConverter建议.它像一种魅力.

I spiked Joe White's IValueConverter suggestion below. It works like a charm.

我已经编写了一个"quickstart"示例,该示例使用一些便宜的字符串替换方法自动执行了ViewModels-> Views的映射.如果未找到表示ViewModel的View,则默认为正在建设中"页面.我将这种方法称为"WPF MVVM White",因为这是Joe White的想法.这是几个屏幕截图.

I've written a "quickstart" example of this that automates the mapping of ViewModels->Views using some cheap string replacement. If no View is found to represent the ViewModel, it defaults to an "Under Construction" page. I'm dubbing this approach "WPF MVVM White" since it was Joe White's idea. Here are a couple screenshots.

第一张图片是基于纯命名约定的情况下的"[SomeControlName] ViewModel"具有对应的"[SomeControlName] View"的情况.第二种情况是ModelView没有任何视图来表示它.没有更长的ViewModel到View映射的ResourceDictionaries.现在是纯粹的命名约定.

The first image is a case of "[SomeControlName]ViewModel" has a corresponding "[SomeControlName]View", based on pure naming convention. The second is a case where the ModelView doesn't have any views to represent it. No more ResourceDictionaries with long ViewModel to View mappings. It's pure naming convention now.

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

I posted a download of the project here: Mvvm.White.Quickstart.zip

原始帖子

我在WPF MVVM上阅读了Josh Smith的很棒的MSDN文章.周末.它注定是一个邪教经典.

I read Josh Smith's fantastic MSDN article on WPF MVVM over the weekend. It's destined to be a cult classic.

我花了好一会儿才想起要WPF渲染 ViewModel 的魔力.

It took me a while to wrap my head around the magic of asking WPF to render the ViewModel.

这就像在说这是一个类,WPF.请找出要使用哪个UI来呈现它."

It's like saying "Here's a class, WPF. Go figure out which UI to use to present it."

对于那些想念这种魔术的人,WPF可以通过在ResourceDictionary映射中查找 ModelView View 并拉出相应的 View . (向下滚动到图10提供视图).

For those who missed this magic, WPF can do this by looking up the View for ModelView in the ResourceDictionary mapping and pulling out the corresponding View. (Scroll down to Figure 10 Supplying a View ).

立即引起我注意的第一件事是,已经有一个很强的命名约定:

The first thing that jumps out at me immediately is that there's already a strong naming convention of:

classNameView  ("View" suffix)
classNameViewModel ("ViewModel" suffix)

我的问题是:

由于 ResourceDictionary 可以通过编程方式进行操作,我想知道是否有人设法使用Regex.将整个内容替换掉,因此查找是自动的,并且任何新的View/ViewModels都将根据其命名约定得到解析?

Since the ResourceDictionary can be manipulated programatically, I"m wondering if anyone has managed to Regex.Replace the whole thing away, so the lookup is automatic, and any new View/ViewModels get resolved by virtue of their naming convention?

我想象中的是对ResourceDictionary的钩子/拦截.

What I'm imagining is a hook/interception into ResourceDictionary.

...还考虑了一种在启动时使用interop提取*View$*ViewModel$类名称以在代码中构建DataTemplate字典的方法:

... Also considering a method at startup that uses interop to pull out *View$ and *ViewModel$ class names to build the DataTemplate dictionary in code:

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

推荐答案

与其编写代码以向ResourceDictionary中显式添加内容,不如按需生成正确的视图?您可以使用ValueConverter来做到这一点.

Rather than writing code to explicitly add things to the ResourceDictionary, how about just generating the right view on demand? You can do this with a ValueConverter.

您的资源将如下所示:

<Views:ConventionOverConfigurationConverter x:Key="MyConverter"/>
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}">
    <ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>

您仍然需要一个DataTemplate资源,但是只要您的ViewModel都有一个通用的基类,您只需要一个DataTemplate即可处理所有这些.

You still need a DataTemplate resource, but as long as your ViewModels all have a common base class, you'll only need one DataTemplate to take care of all of them.

然后定义值转换器类:

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();
    }
}

您需要做的就是在Convert中编写逻辑,这取决于诸如Views和ViewModels是否在同一命名空间中之类的事情.

All you'd need to do is write the logic inside Convert, which will depend on things like whether your Views and ViewModels are in the same namespace or not.

这篇关于WPF MVVM:ResourceDictionary的配置约定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆