【发布时间】:2013-10-20 04:50:39
【问题描述】:
我试图允许用户选择两种格式类型之一来输入双精度值,然后我想在 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');目标属性是“值”(类型“Nullable1')
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 'Nullable1”)
System.Windows.Data 信息:21:BindingExpression 无法从空数据项中检索值。当绑定分离或绑定到没有值的 Nullable 类型时,可能会发生这种情况。绑定表达式:路径=X;数据项=空;目标元素是'DecimalUpDown'(名称='FooBar');目标属性是“值”(类型“Nullable1')
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 'Nullable1”)
...以及其他几行似乎基本相同的内容。
我可以简单地选择两种 Control 类型中的一种来“硬编码”到 xaml 中来代替数据触发器,并且数据绑定工作正常,这让我怀疑设置 DataTrigger 的 Binding 属性会干扰触发器选择的“子”元素的 DataContext。
那么我的问题是,因为我基本上希望整个视图中的最后一件事都将 MyViewModel 作为其 DataContext,有没有什么好方法可以让我的 DataTrigger 选择任一双输入控件类型而不干扰他们的 DataContexts? 或者,如果我从根本上误解了这种情况,那么也许有人可以扔给我一根骨头。
一位和蔼可亲的同事通过这样的绑定设法解决了这种情况: {绑定RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentControl}}, Path=DataContext.X} 但这似乎是一个相当迂回的解决方法。
谢谢!
【问题讨论】: