【问题标题】:Prism and MVVM Light Toolkit棱镜和 MVVM 光工具包
【发布时间】:2012-01-14 00:56:19
【问题描述】:

我正在尝试将 Prism(仅用于 CompositeUI)和 MVVM Light Toolkit(用于 MVVM 架构 =D)放在一起工作,但我在使用 Light ViewModelLocator 时遇到了一些问题。 当我们将定位器用于“简单”的 WPF 应用程序时,我们可以使用 App.xaml 上的应用程序资源,如下所示:

<Application.Resources>
    <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>

但是当我们使用 Prism 时,我们的业务代码在 Module 项目中,并且它没有 App.xaml,然后我尝试将该资源放在 View 资源中:

<Window.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </ResourceDictionary>
</Window.Resources>

它只是关闭了我的设计模式(以及运行时)错误,但视图没有出现在分配给它的区域中。

有人已经尝试过这样做吗? Prism 和 MVVM Light 可以一起工作吗?

这是我的“完整”代码:

(ViewLight.xaml)

<Window x:Class="TryERP2.Financeiro.View.ViewLight"
    ... a lot of NS ...
    mc:Ignorable="d"
    xmlns:vm="clr-namespace:TryERP2.Financeiro.ViewModel"
    d:DesignHeight="150" d:DesignWidth="245" SizeToContent="WidthAndHeight">
    <Window.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
        </ResourceDictionary>
    </Window.Resources>

    <Grid DataContext="{Binding Light, Source={StaticResource Locator}}">
        <Button Content="{Binding MyButtonText}" HorizontalAlignment="Stretch" Name="button1" VerticalAlignment="Stretch" />
    </Grid>
</Window>

ViewLightModel.cs:

public class ViewLightModel : ViewModelBase
{
    public ViewLightModel()
    { }

    public const string MyButtonTextPropertyName = "MyButtonText";
    private string _myButtonText = "Button Text";

    public string MyButtonText
    {
        get
        { return _myButtonText; }

        set
        {
            if (_myButtonText == value)
            { return; }

            _myButtonText = value;
            RaisePropertyChanged(MyButtonTextPropertyName);
        }
    }
}

Financeiro.cs(模块初始化程序类...部分显示...就在我注册和“调用”视图的地方):

        var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
        container.RegisterType<Object, ViewLight>("ViewLight");

        var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
        var main = new Uri("ViewLight", UriKind.Relative);
        regionManager.RequestNavigate("Desktop", main);

“正常”的 MVVM 轻型应用程序有一个 App.xaml 文件,(我认为)没有在 Prism 模块视图中使用。该文件具有以下结构:

<Application x:Class="TryERP2.Financeiro.App"
         ... a lot of NS ...
         xmlns:vm="clr-namespace:TryERP2.Financeiro.ViewModel"
         StartupUri="MainWindow.xaml"
         mc:Ignorable="d">

    <Application.Resources>
        <vm:ViewModelLocator x:Key="Locator"
                             d:IsDataSource="True" />
    </Application.Resources>

</Application>

这就是我执行应用程序时发生的情况。模块上的 View 应该被加载到这个空白处,显示它的 Button,但是什么也没发生:

http://imageshack.us/photo/my-images/818/capturarwy.png

当我尝试更改此视图并在其位置放置一个“简单视图”(不使用 MVVMLight)时,它可以完美运行,如下图所示:

http://imageshack.us/photo/my-images/513/capturar1a.png

【问题讨论】:

  • 你用什么容器? MEF 还是 Unity?您可以为您的视图代码隐藏和 ViewModel 代码隐藏发布代码吗?此外,有关如何将 V-VM 注入区域的代码。 MVVMLight、设计数据等是您在 PRISM/Silverlight 中处理的单独问题。视图未显示很可能是构图错误
  • 我正在使用 Unity。我将通过编辑问题发布整个代码。
  • 除了默认代码外,视图上没有代码隐藏。您认为正在运行的应用程序的解释性屏幕截图会有所帮助吗?
  • 我尝试添加一些直接图片,但我是新用户,不允许新用户发布图片,然后我将它们上传到 ImageShack 并在此处分享他们的链接。随意编辑问题并添加图像。 ;)

标签: c# mvvm prism mvvm-light viewmodellocator


【解决方案1】:

在 ViewLight.xaml 中你应该改变

<Window.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </ResourceDictionary>
</Window.Resources>

<Window.Resources>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Window.Resources>

因为 Window.Resources 已经是一个 ResourceDictionary,而您在其中创建了另一个。您无法在此处访问定位器资源:

<Grid DataContext="{Binding Light, Source={StaticResource Locator}}">

另一种选择是使用 MergedDictionary。

【讨论】:

  • 嗨...我已经尝试删除 标记,但这没有效果。关于绑定,我刚刚将其更改为 标记,因为我遇到了错误。 DataContext 属性的原始位置是 标记。
  • 当它在 Window 标记中时,我收到以下错误消息:“找不到名为 'Locator' 的资源。资源名称区分大小写。”。它曾在一个简单的 MvvmLight 应用程序上工作,其中资源位于 标记中。
  • 您遇到了什么错误?检查 vs 中的输出(在调试模式下)以捕获绑定错误。
  • Grid 和 Locator 资源位于同一个 xaml 中?
  • “输出”没有给出任何错误信息。我说的错误出现在“异常窗口”->Image
【解决方案2】:

对不起。我犯了一个大错误。 您可能已经注意到,我正在构建一个功能区应用程序,并且试图在空白区域下显示控件。 那里可以显示的项目是控件。它不起作用,因为我试图显示一个窗口:

<Window x:Class="TryERP2.Financeiro.View.ViewLight"
... a lot of NS ...
mc:Ignorable="d"
xmlns:vm="clr-namespace:TryERP2.Financeiro.ViewModel"
d:DesignHeight="150" d:DesignWidth="245" SizeToContent="WidthAndHeight">
... etc

我通过将其更改为用户控件而不是窗口来修复它,并且效果很好。

我的新 ViewLight.xaml:

<UserControl x:Class="TryERP2.Financeiro.View.ViewLight"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:vm="clr-namespace:TryERP2.Financeiro.ViewModel"

        d:DesignHeight="150" d:DesignWidth="245">
    <UserControl.Resources>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </UserControl.Resources>

    <Grid DataContext="{Binding Light, Source={StaticResource Locator}}">
        <Button Content="{Binding MyButtonText}" HorizontalAlignment="Stretch" Name="button1" VerticalAlignment="Stretch" />
    </Grid>
</UserControl>

我的新 ViewLight.xaml.cs(代码隐藏):

public partial class ViewLight : UserControl
{
    public ViewLight()
    {
        InitializeComponent();
    }
}

ViewModel 还是一样的。

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 2018-09-13
    相关资源
    最近更新 更多