如何使用DataTemplate设置DataContext
How to use DataTemplate to set DataContext
有人告诉我在 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>
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>
MainViewModel.cs
namespace DataTemplateTesting
{
public class MainViewModel
{
public MainViewModel() { }
}
}
我唯一做的另一件事是为 DataContextChanged 事件向 MainWindow 添加一个处理程序,这样我就可以看到它是否曾经被触发过……它没有。
有什么解决办法吗??
编辑:
并不是说这里不能生成任何东西,而是......这是 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>
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.
}
}
}
<DataTemplate DataType="{x:Type local:MainViewModel}">
<local:MainWindow/>
</DataTemplate>
首先,这个声明并不代表"Create a MainWindow
and set its DataContext
to MainViewModel
"。这实际上意味着每当您看到 MainViewModel
时,只需将 MainWindow
放入可视化树中即可。
其次,您不能将 Window
class 作为 child 添加到另一个 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>
在资源字典中定义:
<DataTemplate DataType="{x:Type local:MainViewModel}">
<local:SomeUserControl/>
</DataTemplate>
并创建一个用户控件:
<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>
如果您的内容动态变化或您正在定义视图 ItemTemplate
,这将很有用。否则只需手动设置 Window
的 DataContext
。
<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>
有人告诉我在 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>
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>
MainViewModel.cs
namespace DataTemplateTesting
{
public class MainViewModel
{
public MainViewModel() { }
}
}
我唯一做的另一件事是为 DataContextChanged 事件向 MainWindow 添加一个处理程序,这样我就可以看到它是否曾经被触发过……它没有。
有什么解决办法吗??
编辑: 并不是说这里不能生成任何东西,而是......这是 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>
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.
}
}
}
<DataTemplate DataType="{x:Type local:MainViewModel}">
<local:MainWindow/>
</DataTemplate>
首先,这个声明并不代表"Create a MainWindow
and set its DataContext
to MainViewModel
"。这实际上意味着每当您看到 MainViewModel
时,只需将 MainWindow
放入可视化树中即可。
其次,您不能将 Window
class 作为 child 添加到另一个 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>
在资源字典中定义:
<DataTemplate DataType="{x:Type local:MainViewModel}">
<local:SomeUserControl/>
</DataTemplate>
并创建一个用户控件:
<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>
如果您的内容动态变化或您正在定义视图 ItemTemplate
,这将很有用。否则只需手动设置 Window
的 DataContext
。
<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>