我检查了那些关于做 DataTemplate 的文章:
以及关于 DataTemplate 的那些取决于属性类型:
我正在尝试根据属性值显示具有不同控件的属性。我有这个部分工作的 Xaml。我有两个问题:
你能帮我找到更好的解决方案来解决这两个问题吗?
这是我的 View 的 xaml 代码,它与具有“ChangingDataType”的 MyContainerViewModel 链接:
<UserControl >
<UserControl.Resources>
<!-- DataTemplate for strings -->
<DataTemplate DataType="{x:Type sys:String}">
<TextBox Text="{Binding Path=.}" HorizontalAlignment="Stretch"/>
</DataTemplate>
<!-- DataTemplate for bool -->
<DataTemplate DataType="{x:Type sys:Boolean}">
<CheckBox IsChecked="{Binding Path=.}" />
</DataTemplate>
<!-- DataTemplate for Int32 -->
<DataTemplate DataType="{x:Type sys:Int32}">
<dxe:TextEdit Text="{Binding Path=.}" MinWidth="50" Mask="d" MaskType="Numeric" HorizontalAlignment="Stretch"/>
<!--<Slider Maximum="100" Minimum="0" Value="{Binding Path=.}" Width="100" />-->
</DataTemplate>
<!-- DataTemplate for decimals -->
<DataTemplate DataType="{x:Type sys:Decimal}">
<!-- <TextBox Text="{Binding Path=.}" MinWidth="50" HorizontalAlignment="Stretch" />-->
<dxe:TextEdit Text="{Binding Path=.}" MinWidth="50" Mask="f" MaskType="Numeric" HorizontalAlignment="Stretch" />
</DataTemplate>
<!-- DataTemplate for DateTimes -->
<DataTemplate DataType="{x:Type sys:DateTime}">
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock Text="{Binding Path=.}"/>
</DataTemplate>
</DataTemplate.Resources>
<DatePicker SelectedDate="{Binding Path=.}" HorizontalAlignment="Stretch"/>
</DataTemplate>
</UserControl.Resources>
<ContentPresenter Content="{Binding MyChangingPropery}"/>
</UserControl>
更多关于2的信息:
我想在 View 中有一个标签和一个根据对象而变化的属性。像这样的东西:
<UserControl>
<UserControl.Resources>
<!-- ...DataTemplate here... -->
</UserControl.Resources>
<StackPanel>
<Label Content="Allo"/>
<ContentPresenter Content="{Binding MyChangingPropery}"/>
</StackPanel>
</UserControl>
但是如果我把DataTemplate放在这个UserControl资源上,也会影响到Label“allo”。所以我必须创建另一个包含 DataTemplate 和 MyChangingProperty 的 View ,以便标签 Allo 不会受到影响。但是为一个属性创建的额外 View 对我来说有点难看,我确信有一种更好的方法来隔离 DataTemplate,以便它只能应用于一个 UIControl。
<UserControl >
<StackPanel>
<Label Content="Allo"/>
<ContentPresenter Content="{Binding MyContainerViewModel}"/>
</StackPanel>
</UserControl>
注意:这里的 MyContainerViewModel 与描述的第一个 View 相关联。
提前致谢!
最佳答案
一种可能的解决方案是使用 DataTemplateSelector
.您不能使用两种方式绑定(bind)原始类型,因为这必须以某种方式通过 DataTemplate
进行引用。我认为 WPF 不支持。DataTemplateSelector
现在选择正确的DataTemplate
根据属性类型搜索权限DataTemplate
按名称在资源中。这也解决了您的问题,您的 DataTemplates
与Label
互动.
所以首先你需要定义一个 DataTemplateSelector
这改变了DataTemplate
根据房产类型:
public class MyDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var fe = (FrameworkElement)container;
var prop = (item as MyViewModelType)?.MyChangingProperty;
if (prop is string)
return fe.FindResource("MyStringDT") as DataTemplate;
else if (prop is bool)
return fe.FindResource("MyBoolDT") as DataTemplate;
// More types...
return base.SelectTemplate(item, container);
}
}
然后你需要更改
UserControl
像这样:<UserControl>
<UserControl.Resources>
<local:MyDataTemplateSelector x:Key="MyDTSelector" />
<!-- DataTemplate for strings -->
<DataTemplate x:Key="MyStringDT">
<TextBox Text="{Binding MyChangingProperty, Mode=TwoWay}"
HorizontalAlignment="Stretch"/>
</DataTemplate>
<!-- DataTemplate for bool -->
<DataTemplate x:Key="MyBoolDT">
<CheckBox IsChecked="{Binding MyChangingProperty, Mode=TwoWay}" />
<!-- More DataTemplates... -->
</DataTemplate>
</UserControl.Resources>
<StackPanel>
<Label Content="Allo"/>
<ContentPresenter Content="{Binding MyContainerViewModel}"
ContentTemplateSelector="{StaticResource MyDTSelector}" />
</StackPanel>
</UserControl>
您可以找到有关
DataTemplateSelector
的更多信息。 here .当然也可以设置
DataType
在这个新的DataTemplates
但它不是必需的,因为 x:Key
无论如何,它们都是独一无二的。但如果你愿意,它必须看起来像这样:<DataTemplate x:Key="MyStringDT" DataType="{x:Type local:MyViewModelType}">
关于wpf - DataTemplate 绑定(bind)取决于属性类型和工作属性绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40003144/