2016-11-05 8 views
1

Я не могу заставить это работать. У меня есть представление), который содержит DataGrid, заполненный элементами наблюдаемой коллекции (MyDataCollection). Каждый элемент MyDataCollection имеет разные свойства (имя, описание, ..., журналы). Журналы представляют собой наблюдаемую коллекцию элементов журнала. Каждый элемент журнала имеет разные свойства (Date, Person, ...).Связывание с вложенным свойством в подсказке строки DataGrid WPF

В моей сетке данных, заполненной элементами MyDataCollection, имеется всплывающая подсказка для набора строк. Как это:

<DataGrid ItemsSource="{Binding MyDataCollection}"> 
      <DataGrid.RowStyle> 
       <Style TargetType="DataGridRow"> 
        <Setter Property="ToolTip"> 
         <Setter.Value> 
          <Border> 
           <Grid Margin="5" MaxWidth="400"> 
            <Grid.RowDefinitions> 
             <RowDefinition Height="*" /> 
             ... 
            </Grid.RowDefinitions> 

            ... 
            <DataGrid x:Name="LogsGrid" Grid.Row="6" ItemsSource="{Binding PlacementTarget.DataContext.Logs, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToolTip}}"> 
             <DataGrid.Columns> 
              <DataGridTextColumn Header="Date" 
               Binding="{Binding Date}" 
               /> 
              <DataGridTextColumn Header="Person" 
               Binding="{Binding Person.FullName}" 
               /> 

             </DataGrid.Columns> 
            </DataGrid> 
           </Grid> 
          </Border> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </DataGrid.RowStyle> 
     </DataGrid> 

Я могу видеть всплывающую подсказку, и я могу видеть DataGrid в подсказке с «Дата» Заголовки и «Человек», но содержание сетки пуст. Похоже, привязка не установлена ​​правильно. Может ли кто-нибудь дать мне руку? Спасибо

Обновление 1: MyDataColletion содержит объекты моего пользовательского класса «Автомобиль». Вот определение автомобиля:

public class Car : INotifyPropertyChanged 
{ 
    public string name; 
    public string description; 
    public Contact assignedTo; 
    public ObservableCollection<Log> logs = new ObservableCollection<Log>(); 
    public string Name 
    { 
     get 
     { 
      return this.name; 
     } 
     set 
     { 
      if (this.name != value) 
      { 
       this.name = value; 
       NotifyPropertyChanged("Name"); 
      } 
     } 
    } 
    public string Description 
    { 
     get 
     { 
      return this.description; 
     } 
     set 
     { 
      if (this.description != value) 
      { 
       this.description = value; 
       NotifyPropertyChanged("Description"); 
      } 
     } 
    } 
    public Contact AssignedTo 
    { 
     get 
     { 
      return this.assignedTo; 
     } 
     set 
     { 
      if (this.assignedTo != value) 
      { 
       this.assignedTo = value; 
       NotifyPropertyChanged("AssignedTo"); 
      } 
     } 
    } 

    public ObservableCollection<Log> Logs 
    { 
     get 
     { 
      return this.logs; 
     } 
     private set //TODO : Check if this is correct 
     { 
      if (this.logs != value) 
      { 
       this.logs = value; 
       NotifyPropertyChanged("Logs"); 
      } 
     } 
    } 

    public Car() 
    { 
     // TODO: Delete this: (only here for testing) 
     Contact c = new Contact(); 
     c.Name = "Test"; 
     c.LastName = "Test"; 
     for (int i = 0; i < 4; i++) 
      AddLog(DateTime.Now, c, new TimeSpan(2, 0, 0)); 
    } 
    public void AddLog(DateTime date, Contact person, TimeSpan time) 
    { 
     Log newLog = new Log(date, person, time); 
     Logs.Add(newLog); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged(string propName) 
    { 
     if (this.PropertyChanged != null) 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 
} 

И мой журнал Класс:

public class Log : INotifyPropertyChanged 
{ 
    DateTime date; 
    Contact person; 
    TimeSpan time; 
    public DateTime Date 
    { 
     get 
     { 
      return this.date; 
     } 
     set 
     { 
      if (this.date != value) 
      { 
       this.date = value; 
       NotifyPropertyChanged("Date"); 
      } 
     } 
    } 
    public Contact Person 
    { 
     get 
     { 
      return this.person; 
     } 
     set 
     { 
      if (this.person != value) 
      { 
       this.person = value; 
       NotifyPropertyChanged("Person"); 
      } 
     } 
    } 
    public TimeSpan Time 
    { 
     get 
     { 
      return this.time; 
     } 
     set 
     { 
      if (this.time != value) 
      { 
       this.time = value; 
       NotifyPropertyChanged("Time"); 
      } 
     } 
    } 

    public Log(DateTime date, Contact person, TimeSpan time) 
    { 
     this.date = date; 
     this.person = person; 
     this.time = time; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged(string propName) 
    { 
     if (this.PropertyChanged != null) 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 
} 
+0

На ItemsSource связывания в подсказке сетке, сначала удалить все TwoWay/PropertyChanged вещи вы положили туда. Если вы прочтете документацию по тем, вы обнаружите, что они не связаны. Затем добавьте «PresentationTraceSources.TraceLevel = High» к этому Binding вместо этого и посмотрите в панели VS Output во время выполнения. Вы увидите там сообщения о том, что происходит, когда он пытается разрешить путь привязки. Вам нужно выяснить, каков фактический объект DataContext для этого привязки. Это скажет вам. –

+0

Я получаю эту ошибку в области вывода VS: System.Windows.Data Error: 40: Ошибка пути BindingExpression: свойство «Логги» не найдено на «объекте» '' DataGrid '(Name =' LogsGrid ')'. BindingExpression: Path = Logs; DataItem = 'DataGrid' (Name = 'LogsGrid'); целевым элементом является «DataGrid» (Name = 'LogsGrid'); target property - «ItemsSource» (тип «IEnumerable») И затем некоторые предупреждения говорят мне, что свойство равно null. Но эти сообщения отображаются, когда приложение запускается, а не когда я добавляю элементы в ObservableCollection. Так что, возможно, источник элементов не обновляется ?? – chincheta73

+0

говорит, что свойство Logs не существует в объекте Source. Не пусто. Отсутствует - в том месте, где он выглядит. Это выглядит не в том месте. Вместо этого попробуйте 'DataContext.Logs'. –

ответ

0

Единственное, что я могу найти в вашем коде, который отлично работает для меня, это Mode=TwoWay в переплёте на LogsGrid.ItemsSource. Это делает для меня исключение, потому что он сообщает Binding, что вы хотите, чтобы LogsGrid записывал новые значения для ItemsSource в исходный код Binding - в этом случае для свойства viewmodel Logs. Мало того, что это не то, что вы хотите, но это фактически невозможно, так как Logs имеет частный сеттер (и, кроме того, DataGrid этого не делает). Отсюда исключение.

UpdateSourceTrigger=PropertyChanged является еще один, который не служит никакой цели, хотя и безвредно на этот раз: Это говорит ему когда писать новые Logs коллекции обратно в Car.Logs. Но опять же, DataGrid не может этого сделать. Он не создает новые значения для свойства. A TextBox назначит новые значения Text исходному свойству, вот для чего TextBox. Но DataGrid этого не делает.

Когда я избавлюсь от этих двух вещей, она отлично работает для меня:

<DataGrid x:Name="LogsGrid" Grid.Row="6" ItemsSource="{Binding Logs}"> 
    <!-- etc. --> 
0

Вместо ItemsSource="{Binding Logs, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">, используйте: ItemsSource="{Binding PlacementTarget.DataContext.Logs, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToolTip}}">.

+0

По-прежнему ничего не показывает – chincheta73

+0

@ chincheta73 извините за скольжение, плз см. Мой обновленный ответ – AnjumSKhan

+0

все еще ничего. В области вывода указано следующее: System.Windows.Data Warning: 108: BindingExpression (hash = 41695345): На уровне 0 - для DataGrid.PlacementTarget найден accessor Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression: свойство PlacementTarget не найден на 'объекте' '' DataGrid '(Name =' LogsGrid ')'. BindingExpression: Path = PlacementTarget.DataContext.Logs; DataItem = 'DataGrid' (Name = 'LogsGrid'); целевым элементом является «DataGrid» (Name = 'LogsGrid'); target свойство - «ItemsSource» (тип «IEnumerable») – chincheta73

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

  • Нет связанных вопросов^_^