2015-10-21 424 views
0

我有2个对象类型显示在同一选项卡内的选项卡上。我正在使用DataTrigger和DataTypeConverter来显示内容。内容显示正常,但我收到以下错误,在输出窗口:System.Windows.Data错误:40:BindingExpression路径错误

System.Windows.Data Error: 40 : BindingExpression path error: 'Taste' property not found on 'object' ''MySmellObject' (HashCode=30266853)'. BindingExpression:Path=Taste; DataItem='MySmellObject' (HashCode=30266853); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Error: 40 : BindingExpression path error: 'Smell' property not found on 'object' ''MyTasteObject' (HashCode=36404074)'. BindingExpression:Path=Smell; DataItem='MyTasteObject' (HashCode=36404074); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') 

这里的XAML:

<Window x:Class="ControlTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:ControlTest" 
     Title="MainWindow" Height="350" Width="525"> 

<Window.Resources> 
    <local:DataTypeConverter x:Key="DataTypeConverter" /> 
</Window.Resources> 

<StackPanel Orientation="Vertical" Width="150"> 
    <TabControl Name="tab" Height="200px" 
      ItemsSource="{Binding MyObjects}"     
      SelectedValuePath="Id" 
      SelectedItem="{Binding MyObject}" 
      >    
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <ContentControl> 
        <ContentControl.Style> 
         <Style TargetType="ContentControl"> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding ElementName=tab,Path=SelectedItem, Converter={StaticResource DataTypeConverter}}" Value="{x:Type local:MyTasteObject}"> 
            <Setter Property="Content"> 
             <Setter.Value> 
              <TextBox Text="{Binding Taste}" ></TextBox> 
             </Setter.Value> 
            </Setter> 
           </DataTrigger> 
           <DataTrigger Binding="{Binding ElementName=tab,Path=SelectedItem, Converter={StaticResource DataTypeConverter}}" Value="{x:Type local:MySmellObject}"> 
            <Setter Property="Content"> 
             <Setter.Value> 
              <TextBox Text="{Binding Smell}" ></TextBox> 
             </Setter.Value> 
            </Setter> 
           </DataTrigger>          
          </Style.Triggers> 
         </Style> 
        </ContentControl.Style> 
       </ContentControl> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 
    </TabControl> 
</StackPanel> 
</Window> 

这里是后面的代码:

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Windows; 
using System.Windows.Data; 

namespace ControlTest 
{ 
    public partial class MainWindow : Window 
    { 
     public List<MyObject> MyObjects { get; set; } 

     public int MyObjectId { get; set; } 
     public MyObject MyObject { get; set; } 

     public MainWindow() 
     { 
      MyObject obj0 = new MySmellObject() { Id = 0, Smell = "Pleasent" }; 
      MyObject obj1 = new MyTasteObject() { Id = 1, Taste = "Mild" }; 

      MyObjects = new List<MyObject> { obj0, obj1 }; 
      MyObjectId = 0; 
      MyObject = obj0; 

      DataContext = this; 

      InitializeComponent(); 
     } 
    } 

    public class MyObject 
    { 
     public int Id { get; set; } 
    } 

    public class MyTasteObject : MyObject 
    { 
     public string Taste { get; set; } 

     public override string ToString() 
     { 
      return Taste; 
     } 
    } 

    public class MySmellObject : MyObject 
    { 
     public String Smell { get; set; } 

     public override string ToString() 
     { 
      return Smell; 
     } 
    } 

    public class DataTypeConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, 
      CultureInfo culture) 
     { 
      return value.GetType(); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, 
      CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

有谁知道为什么我会出现这些错误以及如何修复代码?

回答

2

这里的问题是ContentTemplate是针对在TabControl所有项目应用。最初它只应用于SelectedItem。但切换到新项目后,它将应用于所有加载的项目。

当的SelectedItem改变时,ContentTemplate具有新Content更新ContentControl中,这随后被应用于所有项目。但是因为基础项目具有不同的具体类型(来源于相同的基本类型)。所以一旦模板被应用到不匹配类型的项目上,绑定错误将被无声地报告。

事实上,我们有一个更好的方法来实现你想要的而不需要使用触发器。这就是所谓的DataTemplate为您提供的。只需设置DataType项目类型,然后它会自动与相应的模板,像这样的东西所取代:

<TabControl.ContentTemplate> 
    <DataTemplate>     
     <ContentControl Content="{TemplateBinding Content}"> 
      <ContentControl.Resources> 
       <DataTemplate DataType="{x:Type local:MySmellObject}"> 
        <TextBox Text="{Binding Smell}" ></TextBox> 
       </DataTemplate> 
       <DataTemplate DataType="{x:Type local:MyTasteObject}"> 
        <TextBox Text="{Binding Taste}" ></TextBox> 
       </DataTemplate> 
      </ContentControl.Resources> 
     </ContentControl> 
    </DataTemplate> 
</TabControl.ContentTemplate> 
+0

这工作。非常感谢你。 – Mike

+0

@Mike不客气,我知道它是有效的,因为我运行它。 –

+0

@Mike看起来像你加入SO后,你从来不知道如何接受答案?接受答案非常重要,因为搜索者可以快速浏览应该先阅读的内容,同时找到解决问题的方法。我真的这么想,想要告诉你,Vote占位符下面有一个灰色的V形***标记,只需勾上(它会变绿)。就这样。 –