如何使用 DataTemplateSelector 和 ContentControl 根据视图模型显示不同的控件? [英] How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?
问题描述
我想创建一个简单的窗口,根据选择的视图模型显示不同的控件(SpinEdit
或 TextEdit
).
I want to create a simple window that would display different controls (SpinEdit
or TextEdit
) based on the view-model that is selected.
我已经完成了它背后的代码和逻辑,剩下的就是显示控件(SpinEdit
或 TextEdit
)本身.
I have the code and logic behind it done already, what is left is displaying the control (SpinEdit
or TextEdit
) itself.
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>
我想选择将显示哪个控件(SpinEdit
用于数字,TextEdit
用于名称/字母)
Where in the <ContentControl>
I want to select which control will be displayed (SpinEdit
for numbers and TextEdit
for names/letters)
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
的位置.
Where I want to return a specific DataTemplate
based on the view-model that is created in the c++/cli code.
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();
重点是,覆盖选择器函数中的 item
值始终具有 null
值,我不知道如何在 XAML 中绑定它,因为所有示例我到目前为止已经找到了 ListBox
es 等.没有关于如何基于视图模型显示不同控件的示例.
The point is, the item
value in the overriden selector function always has the null
value and I have no idea how to bind it in XAML since all the examples I've managed to find so far are ListBox
es etc. There's no example on how to display different controls based on the view-model.
按照建议,我在 ContentControl 中添加了 Content 属性,并向它传递了一个参数,该参数现在是选择器中的item"参数.效果很好!
As suggested, I added Content property in the ContentControl and passed it an argument which is now the 'item' argument in the selector. Works just fine!
推荐答案
您不需要 DataTemplateSelector.WPF 提供了一种机制,可以根据 Content 的类型自动为 ContentControl 的 ContentTemplate 选择 DataTemplate.
You do not need a DataTemplateSelector. WPF provides a mechanism that automatically selects a DataTemplate for the ContentTemplate of a ContentControl according to the type of a Content.
当您将此属性设置为未指定 x:Key 的数据类型时,DataTemplate 将自动应用于该类型的数据对象.
When you set this property to the data type without specifying an x:Key, the DataTemplate gets applied automatically to data objects of that type.
因此删除 x:Key
值和您的 DataTemplateSelector,设置 DataType
So drop the x:Key
value and your DataTemplateSelector, set 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 的属性:
and bind the ContentControl's Content to a property that returns either a TInputValueVM or a TInputTextVM:
<ContentControl Content="{Binding InputVM}" />
现在将自动选择适当的数据模板.
The appropriate DataTemplate will now be selected automatically.
这篇关于如何使用 DataTemplateSelector 和 ContentControl 根据视图模型显示不同的控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!