我想创建一个视图的DataTemplate,以显示一个特定的UserControl类型(如texbox,组合框,自定义控件或另一个视图)基于它绑定到的对象的类型。如何根据绑定对象的类型动态更改DataTemplate?
我有以下MVVM框架:
FieldView
是联系在一起的FieldPresenter
一个实例,应为“标签”属性显示<Textblock />
,和用户控件或其他信息查看值(基于类型的值),将其DataSource设置为Presenter的Value属性。目前,我没有第二部分工作。我无法弄清楚如何根据需要编写WPF模板。
视图模型:
public class FieldPresenter : Observable<object>, IFieldPresenter, INotifyPropertyChanged
{
public FieldPresenter() { }
public FieldPresenter(object value)
{
Value = value;
}
object IFieldPresenter.Value
{
get
{
return base.Value;
}
set
{
base.Value = value;
OnPropertyChanged("Value");
}
}
private string _label;
public virtual string Label
{
get
{
return _label;
}
private set
{
_label = value;
OnPropertyChanged("Label");
}
}
}
查看:
<UserControl x:Class="My.Views.FieldView"
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:ViewModels="clr-namespace:My.ViewModels"
mc:Ignorable="d"
d:DesignHeight="24" d:DesignWidth="100">
<UserControl.DataContext>
<ViewModels:FieldPresenter/>
</UserControl.DataContext>
<UserControl.Template>
<ControlTemplate>
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,0,0" HorizontalAlignment="Stretch" Width="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualWidth}">
<TextBlock Text="{Binding Label}" FontWeight="Bold" Height="32" HorizontalAlignment="Stretch"/>
<TextBox Text="{Binding Value}" Height="Auto" HorizontalAlignment="Stretch"/>
</StackPanel>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
我很好奇,如果我想要做的,甚至有可能,或者,如果我可以让我的演示视图模型回归变通办法一个UserControl而不是一个对象值,并让Presenter从对象类型中解析UserControl类型,但是我不觉得我的Presenter应该实例化Controls(或者技术上是一个未绑定的视图)。我应该制作一个界面,如IViewAs<controlType> { controlType View { get; } }
?
在基于数据绑定对象类型的UserControl的某种模板的上述脚本中,我还将如何替换<TextBox Text="{Binding Value}" />
?
的'ContentTemplateSelector'是这个答案完全没有必要的,它需要在这里的唯一原因是因为'DataType'绑定尚未宣布正常。从资源块中删除'ContentTemplateSelector',移除'ContentTemplateSelector =“{StaticResource myTemplateSelector}”',将' DataType =“local:Cube”>“'DataTemplate DataType =”{ x:Type local:Cube}“>'并将 DataType =”local:Sphere“>''更改为':local local:Sphere}>>。代码将完全相同。 –
你是对的,但这样做总是会为同一类型反复地分配相同的模板,例如OP可以通过某种机制指定特定的模板名称,他可以保持对同一模板分配不同模板的控制权键入(他是否需要这样的东西):) – Aybe
现在你可以保持你的VM清洁:) – Aybe