我是WPF的新手,我很确定更有经验的WPF编码人员将能够在几秒钟内发现我的问题。
我试图通过将其声明为模板来在DataContent内部显示UserControl,但是我得到的却是:
这是我代码的相关部分:
<ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
<DataTemplate DataType="{x:Type ViewModels:anotherViewViewModel}">
<Views:anotherView Content="{Binding}"/>
</DataTemplate>
</ContentControl>
视图为:
<UserControl x:Class="materialDesignTesting.Views.anotherView"
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"
xmlns:local="clr-namespace:materialDesignTesting.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Aqua">
</Grid>
</UserControl>
,模型视图为:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace materialDesignTesting.ViewModels
{
class anotherViewViewModel
{
}
}
答案 0 :(得分:2)
<ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
<DataTemplate DataType="{x:Type ViewModels:anotherViewViewModel}">
<Views:anotherView Content="{Binding}"/>
</DataTemplate>
</ContentControl>
正在将DataTemplate
设置为内容控件的实际内容。您需要ContentTemplate
属性(或设置资源):
<ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type ViewModels:anotherViewViewModel}">
<Views:anotherView Content="{Binding}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
仅当Content
的{{1}}属性设置为ContentControl
的实例时,这才起作用。由于它没有绑定或该代码中的任何内容,我猜它仍然为null,因此不会实例化您的视图。
您可以就像@Silvermind所建议的那样直接使用anotherViewModel
,但是我怀疑您要进行某种动态切换。如果是这种情况,您想坚持使用当前的方法,只需给Views:anotherView
展示一下即可!
相关地,除非ContentControl
也是 一个anotherView
,否则它可能没有ContentControl
属性,因此设置/绑定是毫无意义的。 Content
将anotherView
的实例作为DataContext来使用,因为它位于数据模板中,而无需其他代码。
答案 1 :(得分:1)
通常,您将定义一个模板,例如:
<DataTemplate DataType="{x:Type local:FooVM}">
<local:FooUserControl/>
</DataTemplate>
这在合并在app.xaml中的资源字典中。 然后绑定
<ContentControl Content="{Binding ContentProperty}"/>
在viewmodel中是数据上下文,ContentProperty设置为Viewmodel的实例,例如FooVM,以便导航到foo。 导航时,最好将ContentProperty设置为null,然后再设置新的虚拟机,除非您希望在用户导航到同一视图时保留视图状态。
无论如何,当您执行此操作时,从该模板生成的用户控件FooUserControl就会将其内容(您的vm)作为其数据上下文。
这是一个简化的示例:
public class MainWindowViewModel : INotifyPropertyChanged
{
private object currentViewModel;
public object CurrentViewModel
{
get { return currentViewModel; }
set { currentViewModel = value; RaisePropertyChanged(); }
}
private RelayCommand<Type> navigateCommand;
public RelayCommand<Type> NavigateCommand
{
get
{
return navigateCommand
?? (navigateCommand = new RelayCommand<Type>(
vmType =>
{
CurrentViewModel = null;
CurrentViewModel = Activator.CreateInstance(vmType);
}));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
视图:
<Window x:Class="wpf_Navigation_ViewModelFirst.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:wpf_Navigation_ViewModelFirst"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:LoginViewModel}">
<local:LoginUC/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:UserViewModel}">
<local:UserUC/>
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Button Content="Login Page"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:LoginViewModel}"
/>
<Button Content="User Page"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:UserViewModel}"
/>
</StackPanel>
<ContentControl Grid.Column="1"
Content="{Binding CurrentViewModel}"
/>
</Grid>