Window.Content与DataTemplate

时间:2011-03-21 19:49:50

标签: wpf mvvm

我有一个DataTemplate它的DataType是MyViewModel,如果我这样做的话:

<ContentPresenter Content="{Binding SomeViewModel}"/>

如果我将“SomeViewModel”设置为MyViewModel(在DataTemplate中定义的VM),我可以在视图上看到DataTemplate渲染,这是预期的。

我想做的是:

Window host = new Window()
host.Content = new MyViewModel();
host.Show();

我希望这会显示一个带有与MyViewModel渲染相关联的DataTemplate的窗口,而不是我得到一个带有单行的窗口,即我的ViewModel的路径。

我做错了什么?

2 个答案:

答案 0 :(得分:4)

可能是资源位置问题。之前定义的DataTemplate在哪里?它在App.xaml的ResourceDictionary中吗?尝试在那里添加DataTemplate

<Application ...>
     <Application.Resources>
         <DataTemplate DataType="{x:Type MyViewModel}">
             <!-- View -->
         </DataTemplate>
     </Application.Resources>
</Application>

在更好的情况下,您可以将其放在与ResourceDictionary中的其他人合并的App.xaml中。

编辑:微小的工作示例。

<Application x:Class="DataTemplateTest.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Startup="Application_Startup">
    <Application.Resources>
        <DataTemplate DataType="{x:Type sys:Int32}">
            <Border Background="Red">
                <TextBlock Text="{Binding}" />
            </Border>
        </DataTemplate>
    </Application.Resources>
</Application>

适当的代码隐藏:

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var window = new Window();
        window.Content = 42;
        window.Show();
    }
}

编辑2:因为您说这段代码是在WPF AddIn

  1. 如果DataTemplate位于主机应用程序中,则无效。 Host和AddIn UI不以这种方式相互通信,因为AddIn只是HwndSource
  2. 如果DataTemplate位于AddIn中的ResourceDictionary,您可以这样加载:

    var window = new Window();
    window.Resources.MergedDictionaries.Add(
        new ResourceDictionary
        {
            Source =
                new Uri("pack://application:,,,/AddInAssembly;component/Resources.xaml",
                        UriKind.Relative)
        });
    window.Content = ...;
    window.Show();
    

答案 1 :(得分:0)

你应该在你的问题中添加以下信息:datatemplate / usercontrol定义在哪里(addin.dll)?在哪里定义了“窗口”(mainproject)?

如果你的viewmodel和datatemplate在你的addin.dll中并且你的“窗口”在你的主项目中,那么你必须至少将你的datatemplate作为资源添加到窗口。

如果您的viewmodel和datatemplate以及您的“窗口”在您的addin.dll中并且您只是在您的主项目“window.show”中调用,那么您必须将datatemplate作为资源添加到您的插件中的“窗口”的.dll。

我使用mef来构建wpf插件应用程序,我在addin.dlls中使用以下语法:

 <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/YourAddinDllName;Component/ResourceDictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>

顺便说一下,如果只公开你的viewmodel并在你的mainproject中调用它。你必须公开和注册你的datatemplate。让我知道你的插件是如何工作的。