我试图允许用户选择两种格式类型之一来输入双精度值,然后我想在 xaml 中使用 DataTrigger 来选择两种单独的控件类型之一,供用户根据格式输入这些值已经选择。
我有一个视图和一个视图模型。视图模型具有如下属性:
public class MyViewModel
{
public string DoubleFormat {get;set;}
public double X {get;set;}
public double Y {get;set;}
public double Z {get;set;}
}
应用程序会将 DoubleFormat 属性设置为“FormatA”或“FormatB”,以便触发 DataTrigger。
我认为的 xaml 如下所示:
<DataTemplate x:Key="FormatAEditTemplate" DataType="common:MyViewModel">
<util:FormatAEditorControl Value="{Binding X}"/>
</DataTemplate>
<DataTemplate x:Key="FormatBEditTemplate" DataType="common:MyViewModel">
<wpftk:DecimalUpDown Value="{Binding X}" />
</DataTemplate>
<DataTemplate x:Key="MyEditTemplate" DataType="common:MyViewModel">
<ContentControl x:Name="MyDoubleInputControl" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding DoubleFormat}" Value="FormatA">
<Setter TargetName="MyDoubleInputControl" Property="ContentTemplate" Value="
{StaticResource FormatAEditTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding DoubleFormat}" Value="FormatB">
<Setter TargetName="MyDoubleInputControl" Property="ContentTemplate" Value="
{StaticResource FormatBEditTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
因此,在触发器中,我实际上是在尝试将 ContentControl 的 ContentTemplate 属性设置为等于顶部的两个模板值中的任何一个,呈现 util:FormatAEditorControl 或 wpftk:DecimalUpDown 供用户编辑属性 X 的双精度值在视图模型上。
触发器确实起作用并且呈现了正确的控件类型,但是输入控件本身的数据绑定不起作用。控件已呈现,但双属性没有“0.0”默认值,更新 U/I 中的属性也不会影响 viewmodel 属性值。当我打开大量 WPF 输出日志记录时,我还在“输出”窗口中获得以下输出:
System.Windows.Data 信息:41:BindingExpression 路径错误:找不到“对象”的“X”属性,因为数据项为空。这可能是因为数据提供者尚未生成任何数据。绑定表达式:路径=X;数据项=空;目标元素是'DecimalUpDown'(名称='FooBar');目标属性为“值”(类型为“Nullable 1')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=X; DataItem=null; target element is 'DecimalUpDown' (Name='FooBar'); target property is 'Value' (type 'Nullable
1”) System.Windows.Data 信息:21:BindingExpression 无法从空数据项中检索值。当绑定被分离或绑定到没有值的 Nullable 类型时,可能会发生这种情况。绑定表达式:路径=X;数据项=空;目标元素是'DecimalUpDown'(名称='FooBar');目标属性是“值”(类型“可空1')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=X; DataItem=null; target element is 'DecimalUpDown' (Name='FooBar'); target property is 'Value' (type 'Nullable
1”)
...以及其他几行似乎基本相同的内容。
我可以简单地选择两种Control类型中的一种来“硬编码”到xaml中来代替数据触发器,并且数据绑定工作正常,这让我怀疑设置DataTrigger的Binding属性会干扰DataContext触发器选择的“子”元素。
那么我的问题是,由于我基本上希望整个视图中的最后一件事都将 MyViewModel 作为其 DataContext,有没有什么好方法可以让我的 DataTrigger 选择任一双输入控件类型而不干扰它们的 DataContext? 或者,如果我从根本上误解了这种情况,那么也许有人可以扔给我一根骨头。
一位亲切的同事通过这样的绑定设法解决了这种情况: {Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentControl}}, Path=DataContext.X} 但这似乎是一个相当迂回的解决方法。
谢谢!