2016-11-05 2 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에는 내 맞춤 클래스 "자동차"의 개체가 포함되어 있습니다. 여기에 자동차의 정의 :

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 물건을 제거합니다. 이 문서를 읽으면 관련이 없다는 것을 알 수 있습니다. 그런 다음 대신에 Binding에'PresentationTraceSources.TraceLevel = High'을 추가하고 런타임에 VS 출력 창을보십시오. 바인딩 경로를 해결하려고 할 때 발생하는 메시지가 표시됩니다. DataContext가 해당 Binding에 대한 실제 객체를 알아야합니다. 그게 당신에게 말할 것입니다. –

+0

VS 출력 창에서이 오류가 발생합니다. 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은 그렇게하지 않습니다.) 실제로 불가능합니다. 따라서 예외.이 Logs 컬렉션을 다시 Car.Logs 새로운 작성할 때 즉, 그것을 를 알려줍니다 : 소득이 시간이 비록

UpdateSourceTrigger=PropertyChanged

은 아무 가치가없는 또 다른 하나입니다. 하지만 다시 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 미안 해요, plz 내 업데이트 된 답변보기 – 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