如何使用DataTemplate设置DataContext

Tom*_*lla 2 data-binding wpf datacontext datatemplate

我被告知在MVVM中为视图设置DataContext的最佳方法是使用DataTemplate.所以我试图通过使用DataTemplate将MainWindow的DataContext设置为MainWindowViewModel的实例.

我一直无法弄清楚如何.

我已经尝试将ResourceDictionary放在不同的地方(在App.xaml中,在Window.Resources标签中......)

我用谷歌搜索无济于事.这就是我所拥有的......(它不起作用,但在这里它是)

App.xaml中:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary1.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:DataTemplateTesting" >

    <DataTemplate DataType="{x:Type local:MainViewModel}">
        <local:MainWindow/>
    </DataTemplate>

</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

MainViewModel.cs

namespace DataTemplateTesting
{
    public class MainViewModel
    {
        public MainViewModel() { }
    }
}
Run Code Online (Sandbox Code Playgroud)

我做的唯一另一件事是为MainWindow添加一个处理程序,用于DataContextChanged事件,所以我可以看到它是否曾被激活......它没有.

任何想法如何解决这一问题??

编辑:这里没有任何东西无法生成,但是......这里是MainWindow代码.

MainWindow.xaml

<Window x:Class="DataTemplateTesting.MainWindow"
        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"
        xmlns:local="clr-namespace:DataTemplateTesting"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContextChanged="Window_DataContextChanged"        >
    <Grid>

    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

MainWindow.xaml.cs

namespace DataTemplateTesting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            int i = 10; //This line exists solely to put a debug stop on.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Yus*_*dın 6

<DataTemplate DataType="{x:Type local:MainViewModel}">
    <local:MainWindow/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

首先,这种说法并不意味着"创建MainWindow并设置其DataContextMainViewModel".它实际上意味着每当你看到MainViewModel刚刚放入MainWindow可视化树时.

其次,你不能将一个Window班级作为孩子添加到另一个班级Visual.如果你尝试,你会得到一个例外Window must be the root of the tree. Cannot add Window as a child of Visual.

正确的方法是这样的:

<Window x:Class="DataTemplateTesting.MainWindow"
    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"
    xmlns:local="clr-namespace:DataTemplateTesting"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ContentControl>
        <ContentControl.Content>
            <local:MainViewModel/>
        </ContentControl>
    </ContentControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

在资源字典中定义它:

<DataTemplate DataType="{x:Type local:MainViewModel}">
    <local:SomeUserControl/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

并创建一个用户控件:

<UserControl x:Class="DataTemplateTesting.SomeUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox/>
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

如果您的内容动态更改或您正在定义ItemTemplate视图,这将非常有用.否则,只是设置DataContextWindow手动.

<Window x:Class="DataTemplateTesting.MainWindow"
        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"
        xmlns:local="clr-namespace:DataTemplateTesting"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainViewModel>
    </Window.DataContext>

    <Grid>

    </Grid>
Run Code Online (Sandbox Code Playgroud)

  • `首先,这个语句并不意味着“创建一个 MainWindow 并将其 DataContext 设置为 MainViewModel”。实际上,这意味着每当您看到 MainViewModel 时,只需将 MainWindow 放入可视化树中即可。这并不完全正确,因为它实际上将“DataContext”设置为触发数据模板的“MainViewModel”实例。我不知道它在哪里完成,但它已经完成了。 (2认同)