我想創建一個視圖的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