如何将DataTemplateSelector与ContentControl结合使用以基于视图模型显示不同的控件?

时间:2018-11-09 12:59:31

标签: c# wpf datatemplateselector

我想创建一个简单的窗口,该窗口根据所选的视图模型显示不同的控件(u32SpinEdit)。

我已经完成了背后的代码和逻辑,剩下的是显示控件(TextEditSpinEdit)本身。

XAML:

TextEdit

我要在 <dx:DXWindow.Resources> <DataTemplate x:Key="DataTemplate_Value"> <dxe:SpinEdit Height="23" MinWidth="200" Width="Auto" Text="{Binding Path=Value, Mode=TwoWay}" Mask="{Binding Mask, Mode=OneWay}" MaxLength="{Binding Path=InputLength}" /> </DataTemplate> <DataTemplate x:Key="DataTemplate_Text"> <dxe:TextEdit Height="23" MinWidth="200" Width="Auto" Text="{Binding Path=Value, Mode=TwoWay}" MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}" MaxLength="{Binding Path=InputLength}"/> </DataTemplate> <local:PropertyDataTemplateSelector x:Key="templateSelector" DataTemplate_Value="{StaticResource DataTemplate_Value}" DataTemplate_Text="{StaticResource DataTemplate_Text}" /> </dx:DXWindow.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" > <Label x:Uid="Label" MinHeight="24" MinWidth="60" Content="Value" /> <ContentControl ContentTemplateSelector="{StaticResource templateSelector}" /> </StackPanel> <StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom"> <Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" /> <Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" /> </StackPanel> 中选择要显示的控件(数字为<ContentControl>,名称/字母为SpinEdit

C#:

TextEdit

我要根据c ++ / cli代码中创建的视图模型返回特定的 public class PropertyDataTemplateSelector : DataTemplateSelector { public DataTemplate DataTemplate_Value { get; set; } public DataTemplate DataTemplate_Text { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var selector = item as TInputBaseVM; if(selector is TInputValueVM) return DataTemplate_Value; return DataTemplate_Text; } }

C ++ / cli:

DataTemplate

问题是,重写选择器函数中的 TInputValueVM ^oExchange_Value; TInputTextVM ^oExchange_Text; int inputFormat = A_Attributes.GetInputFormat(); if(inputFormat) oExchange_Text = gcnew TInputTextVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()), A_Attributes.GetInputLength(), gcnew System::String(A_Attributes.GetInitialText())); else oExchange_Value = gcnew TInputValueVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()), A_Attributes.GetInputLength(), A_Attributes.GetInitialValue()); Dialogs::TSignalNumberPositionDialog^ dialog = gcnew Dialogs::TSignalNumberPositionDialog(); if(inputFormat) dialog->DataContext = oExchange_Text; else dialog->DataContext = oExchange_Value; dialog->ShowDialog(); 值始终具有item值,由于我设法找到了所有示例,因此我不知道如何在XAML中绑定它null es等。到目前为止,没有关于如何基于视图模型显示不同控件的示例。

编辑:

根据建议,我在ContentControl中添加了Content属性,并为其传递了一个参数,该参数现在是选择器中的“ item”参数。效果很好!

2 个答案:

答案 0 :(得分:1)

您不需要DataTemplateSelector。 WPF提供了一种机制,可以根据Content的类型自动为ContentControl的ContentTemplate选择一个DataTemplate。

Data​Template.​Data​Type中所述:

  

在不指定x:Key的情况下将此属性设置为数据类型时,DataTemplate会自动应用于该类型的数据对象。

因此,删除x:Key值和您的DataTemplateSelector,设置DataType

<dx:DXWindow.Resources>
    <DataTemplate DataType="{x:Type local:TInputValueVM}">
        <dxe:SpinEdit Height="23" MinWidth="200" Width="Auto"
                      Text="{Binding Path=Value, Mode=TwoWay}"
                      Mask="{Binding Mask, Mode=OneWay}" 
                      MaxLength="{Binding Path=InputLength}" />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:TInputTextVM}">
        <dxe:TextEdit Height="23" MinWidth="200" Width="Auto"
                      Text="{Binding Path=Value, Mode=TwoWay}"
                      MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}"
                      MaxLength="{Binding Path=InputLength}"/>
    </DataTemplate>
</dx:DXWindow.Resources>

并将ContentControl的内容绑定到返回TInputValueVM或TInputTextVM的属性:

<ContentControl Content="{Binding InputVM}" />

现在将自动选择适当的DataTemplate。

答案 1 :(得分:0)

您必须在Content的{​​{1}}属性中添加一些值。该值将作为ContentControl传递到SelectTemplate。您可能应该将其绑定到ViewModel中的某些属性,以便能够从那里更改它。