2015-10-21 3 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 с обновлением ContentControl с новым Content, это применяется ко всем элементам. Но поскольку базовые элементы имеют разные конкретные типы (исходя из одного и того же базового типа). Поэтому, как только шаблон применяется к элементу с несогласованным типом, ошибка привязки будет сообщаться молча.

На самом деле у нас есть лучший способ добиться того, чего вы хотите, без использования триггеров. Вот что дает вам так называемый 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

@ Майк выглядит так, как вы присоединились к SO, вы никогда не знали, как принять ответ? Очень важно принять ответ, потому что поисковики могут быстро сэкономить то, что следует прочитать сначала, находя какое-то решение своей проблемы. Я действительно так думаю и хотел бы сообщить вам, что под Vote-заполнителем есть серая *** V-образная *** отметка, просто отметьте ее (она станет зеленой). Это все. –

Смежные вопросы