用户控件中同一 ViewModel 的两个视图
我有一个可重用的用户控件,其背后有一个视图模型。我正在尝试在同一数据的不同视图之间切换。目前正在尝试使用虚拟机上的模式属性来完成此操作。
我创建了一个 DataTemplateSelector,如下所示:
<UserControl x:Class="MyUserControl">
<UserControl.Resources>
<DataTemplate x:Key="ColumnTemplate">
<StackPanel>
<Label Text="{Binding Name}"></Label>
<Label Text="{Binding Address}"></Label>
<Label Text="{Binding Occupation}"></Label>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="AvatarTemplate">
<StackPanel>
<Image Source="{Binding ProfilePicture}"></Image>
<Label Text="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
<local:DisplayTemplateSelector ColumnTemplate="{StaticResource ColumnTemplate}" AvatarTemplate="{StaticResource AvatarTemplate}" x:Key="displayTemplateSelector" />
</UserControl.Resources>
<Grid>
<ContentControl Name="cpDisplay" Content="{Binding}" ContentTemplateSelector="{StaticResource displayTemplateSelector}" />
</Grid>
</UserControl>
使用类:
class DisplayTemplateSelector : DataTemplateSelector
{
public DataTemplate ColumnTemplate {get;set;}
public DataTemplate AvatarTemplate {get;set;}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
MainViewModel vm = (MainViewModel)item;
switch (vm.Mode)
{
case MainViewModel.DisplayMode.Column:
return ColumnTemplate;
case MainViewModel.DisplayMode.Avatar:
return AvatarTemplate;
default:
return AvatarTemplate;
}
}
}
此用户控件位于 MyWindow 中:
<Grid>
<controls:MyUserControl x:Name="MyUserControl" DataContext="{Binding}" Margin="0"/>
</Grid>
它是用我的视图模型实例化的:
MyWindow w = new MyWindow(_vm);
w.Show();
我遇到的问题是 item
在 MainViewModel vm = ( MainViewModel)项目
。就像我试图在绑定数据之前根据数据设置数据模板?
无论如何,是否可以选择不基于数据对象的所需数据模板 - 而是作为用户控件上的属性或类似属性?
I have a re-usable usercontrol with a viewmodel behind it. I'm trying to switch between different views of the same data. Currently trying to use a Mode property on the VM to accomplish this.
I've created a DataTemplateSelector like so:
<UserControl x:Class="MyUserControl">
<UserControl.Resources>
<DataTemplate x:Key="ColumnTemplate">
<StackPanel>
<Label Text="{Binding Name}"></Label>
<Label Text="{Binding Address}"></Label>
<Label Text="{Binding Occupation}"></Label>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="AvatarTemplate">
<StackPanel>
<Image Source="{Binding ProfilePicture}"></Image>
<Label Text="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
<local:DisplayTemplateSelector ColumnTemplate="{StaticResource ColumnTemplate}" AvatarTemplate="{StaticResource AvatarTemplate}" x:Key="displayTemplateSelector" />
</UserControl.Resources>
<Grid>
<ContentControl Name="cpDisplay" Content="{Binding}" ContentTemplateSelector="{StaticResource displayTemplateSelector}" />
</Grid>
</UserControl>
With the class:
class DisplayTemplateSelector : DataTemplateSelector
{
public DataTemplate ColumnTemplate {get;set;}
public DataTemplate AvatarTemplate {get;set;}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
MainViewModel vm = (MainViewModel)item;
switch (vm.Mode)
{
case MainViewModel.DisplayMode.Column:
return ColumnTemplate;
case MainViewModel.DisplayMode.Avatar:
return AvatarTemplate;
default:
return AvatarTemplate;
}
}
}
This usercontrol sits in MyWindow:
<Grid>
<controls:MyUserControl x:Name="MyUserControl" DataContext="{Binding}" Margin="0"/>
</Grid>
Which is instantiated with my viewmodel:
MyWindow w = new MyWindow(_vm);
w.Show();
The problem I have is that item
is null during MainViewModel vm = (MainViewModel)item
. It's like I'm trying to set the datatemplate based on data, before the data is bound?
Is there anyway to choose the desired datatemplate not based on the dataobject - but as a property or similar on the usercontrol?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
方法有很多,但这里有几种:
或者:
There are many ways, but here are a couple:
or:
请参阅 DataTemplateSelector 类
DataTemplateSelector
See DataTemplateSelector Class
DataTemplateSelector
好的,终于通过使用用户控件上的属性和后面的一些代码来按照我需要的方式工作:
我删除了 DataTemplateSelector 代码并简单地定义了数据模板并使用:
Ok, finally got this to work how I needed by using a property on the usercontrol and some code behind:
I removed the DataTemplateSelector code and simply defined the datatemplates and used: