如何将DataTemplateSelector与ContentControl一起使用,以根据视图模型显示不同的控件



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

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

XAML:

<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表示数字,TextEdit表示名称/字母(

C#:

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

C++/cli:

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();

重点是,overriden选择器函数中的item值总是有null值,我不知道如何在XAML中绑定它,因为到目前为止我找到的所有示例都是ListBoxes等。没有关于如何基于视图模型显示不同控件的示例。

编辑:

按照建议,我在ContentControl中添加了Content属性,并向它传递了一个参数,该参数现在是选择器中的"item"参数。工作得很好!

您不需要DataTemplateSelector。WPF提供了一种根据内容的类型自动为ContentControl的ContentTemplate选择DataTemplate的机制。

如数据中所述​样板​数据​类型:

当您将此属性设置为数据类型而不指定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。

您必须在ContentControlContent属性中添加一些值。该值将作为object item传递给SelectTemplate。您可能应该将ViewModel中的某些属性绑定到它,以便能够从那里更改它。

最新更新