2016-11-05 17 views
1

これは機能しません。私は、観測可能なコレクション(MyDataCollection)の項目で構成されたDataGridを含むビューを持っています。 MyDataCollectionの各項目には、異なるプロパティ(名前、説明、...、ログ)があります。ログは、ログ項目の観測可能なコレクション自体です。すべてのログ項目には異なるプロパティ(日付、人物、...)があります。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には、私のカスタムクラス "Car"のオブジェクトが含まれています。ここでは車の定義:

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

を、最初にあなたがそこに置かすべての双方向/のPropertyChangedものを削除します。あなたがそれらの文書を読んでいれば、彼らは無関係であることがわかります。代わりに 'PresentationTraceSources.TraceLevel = High'をそのBindingに追加し、実行時にVS出力ペインを調べます。バインディングパスを解決しようとするときに何が起こるかを示すメッセージが表示されます。 DataContextがそのBindingの実際のオブジェクトを調べる必要があります。それはあなたに伝えます。 –

+0

System.Windows.Dataエラー:40:BindingExpressionパスエラー: 'Logs'プロパティが 'object' '' 'DataGrid'(Name = 'LogsGrid') 'に見つかりませんでした。 BindingExpression:パス=ログ; DataItem = 'DataGrid'(Name = 'LogsGrid');ターゲット要素は 'DataGrid'(Name = 'LogsGrid')です。ターゲットプロパティが 'ItemsSource'(タイプ 'IEnumerable') そして、そのプロパティがnullであることを伝える警告が表示されます。しかし、このメッセージは、ObservableCollectionに要素を追加したときではなく、アプリケーションの実行時に表示されます。だから、アイテムのソースが更新されていない可能性がありますか? – chincheta73

+0

これは、LogsプロパティがSourceオブジェクトに存在しないことを伝えています。空ではない。存在しない - それが見ている場所で。間違った場所を探しています。代わりに 'DataContext.Logs'を試してみてください。 –

答えて

0

完全に私のために動作しないあなたのコードで見つけることができるのはLogsGrid.ItemsSourceのバインディングにMode=TwoWayです。これはBindingに、ItemsSourceの新しい値をBindingソース(この場合は、ビューモデルのLogsプロパティ)に書き戻したいと伝えているため、私には例外がスローされます。あなたが望むものではないだけでなく、Logsにはプライベートセッターがあります(そして、とにかくDataGridはそれをしません)。したがって、例外。

UpdateSourceTrigger=PropertyChangedは無害この時間が、何の目的を果たしていない別のものです:が戻っCar.Logsに新しいLogsコレクションを書くことときには、それを伝えます。しかし、やはりDataGridはそれを行うことはできません。このプロパティの新しい値は作成されません。 TextBoxは、新しいTextの値をソースプロパティに割り当てます。これはTextBoxの値です。しかし、DataGridはそうしていません。私はこれら二つのことを取り除く

は、それは私のために正常に動作します:ツールチップのグリッドにバインドのItemsSourceに

<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警告:108:BindingExpression(ハッシュ= 41695345):レベル0 - DataGrid.PlacementTargetがアクセサを検出した場合 System.Windows.Dataエラー:40:BindingExpressionパスエラー: 'PlacementTarget'プロパティ'オブジェクト' '' DataGrid '(Name =' LogsGrid ')'には見つかりませんでした。 BindingExpression:Path = PlacementTarget.DataContext.Logs; DataItem = 'DataGrid'(Name = 'LogsGrid');ターゲット要素は 'DataGrid'(Name = 'LogsGrid')です。ターゲットプロパティが 'ItemsSource'(タイプ 'IEnumerable') – chincheta73

関連する問題