2016-11-05 84 views
1

我无法正常工作。我有一个视图),其中包含一个DataGrid,其中包含可观察集合(MyDataCollection)的项目。 MyDataCollection的每一项都有不同的属性(名称,描述,...,日志)。日志是Log项目的可观察集合本身。每个日志项目都有不同的属性(日期,人员...)。绑定到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> 

我可以看到提示,我可以看到数据网格与头“日期”和“人”,但格内容为空的提示。看起来绑定设置不正确。任何人都可以帮我一把吗?谢谢

更新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在工具提示电网结合,首先删除所有你把在那里双向/的PropertyChanged东西。如果你阅读那些你会发现它们不相关的文档。然后将'PresentationTraceSources.TraceLevel = High'添加到该绑定,并在运行时查看VS输出窗格。您会在那里看到消息,告诉您在尝试解析绑定路径时会发生什么。你需要找出DataContext对那个Binding实际的对象。那会告诉你。 –

+0

我在VS输出窗格中得到这个错误:System.Windows.Data错误:40:BindingExpression路径错误:'对象'''DataGrid'(Name ='LogsGrid')'找不到'Logs'属性。 BindingExpression:路径=日志; DataItem ='DataGrid'(Name ='LogsGrid');目标元素是'DataGrid'(Name ='LogsGrid');目标属性是'ItemsSource'(类型'IEnumerable') 然后一些警告告诉我,该属性为空。但是这个消息在应用程序运行时显示,而不是在向ObservableCollection添加元素时显示。所以也许项目源不被更新? – chincheta73

+0

它告诉你Source对象上不存在Logs属性。不是空的。不存在 - 在它正在寻找的地方。它看着错误的地方。改为使用'DataContext.Logs'。 –

回答

0

我可以在你的代码中找到的唯一不适合我的工作是在LogsGrid.ItemsSource上绑定Mode=TwoWay。这对我来说是一个例外,因为它告诉Binding,您希望LogsGridItemsSource的新值写回到Binding源 - 在本例中为视图模型的Logs属性。这不仅仅是你想要的,但它实际上是不可能的,因为Logs有一个私人setter(此外,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对不起,slz看到我更新的回答 – AnjumSKhan

+0

仍然没有。输出窗格这样说:System.Windows.Data Warning:108:BindingExpression(hash = 41695345):在级别0 - 对于DataGrid.PlacementTarget找到访问者 System.Windows.Data错误:40:BindingExpression路径错误:'PlacementTarget'属性在'object''DataGrid'(Name ='LogsGrid')'中找不到。 BindingExpression:路径= PlacementTarget.DataContext.Logs; DataItem ='DataGrid'(Name ='LogsGrid');目标元素是'DataGrid'(Name ='LogsGrid');目标属性是'ItemsSource'(类型'IEnumerable') – chincheta73