2017-11-08 3 views
1

클래스에 인덱싱 된 속성을 만들었으므로 DataGrid (각 셀을 인덱싱 된 속성의 해당 항목으로)에 DataGridTemplateColumn의 각 셀에 바인딩을 설정해야합니다.DataGrid 셀을 인덱싱 된 속성에 바인딩

작업 일정 생성 응용 프로그램입니다. 그리드의 각 셀은 직원 및 이동과 관련된 데이터를 표시합니다. 이동중인 직원이 많을수록 그리드가 오른쪽으로 늘어납니다 (즉, 더 많은 열 추가). 그리드는 프로그래밍 방식으로 작성되고 채워지는 데이터 구조를 표시하며 데이터베이스 테이블에 바인딩되지 않습니다. 이 포럼에서보다 쉽게 ​​제시하고 코드를 검사 할 목적으로 모든 것을 필수 요소로 축소했습니다. 내가 제대로 바인딩을 설정할 수

enter image description here

이것은 분명히 잘못된 것입니다 : 여기

는 그림이다. StackPanel의 필드를 인덱싱 된 속성의 첫 번째 항목 또는 다른 항목에 바인딩 할 수 있지만 인덱싱 된/매개 변수화 된 설정에는 바인딩 할 수 없습니다.

<Grid HorizontalAlignment="Left"> 
    <DataGrid x:Name="grdSch" HorizontalAlignment="Left" Height="400" VerticalAlignment="Top" Margin="8,0,0,0" AutoGenerateColumns="False" SelectionUnit="Cell"/> 
</Grid> 
<Page.Resources> 
    <DataTemplate x:Key="SPI_Template"> 
     <StackPanel> 
      <TextBlock Text="{Binding Path=shftDate}"/> 
      <TextBlock Text="{Binding Path=shftKind}"/> 
     </StackPanel> 
    </DataTemplate> 
    <DataTemplate x:Key="SEI_Template"> 
     <StackPanel> 
      <TextBlock Text="{Binding Path=data[0].emplName}"/> 
      <TextBlock Text="{Binding Path=data[0].shftTime}"/> 
     </StackPanel> 
    </DataTemplate> 
</Page.Resources> 

및 열을 생성하는 코드 : 다음 data[] 속성을 인덱싱

private void Page_Loaded(object sender, RoutedEventArgs e) 
    { 
     // Create the grid columns 
     DataGridTemplateColumn col = new DataGridTemplateColumn(); 
     col.Header = "Shift"; 
     col.CellTemplate = (DataTemplate)FindResource("SPI_Template"); 
     grdSch.Columns.Add(col); 
     for (int i = 0; i < 30; i++) 
     { 
      col = new DataGridTemplateColumn(); 
      col.Header = "Employee " + (i + 1); 
      col.Width = 100; 
      col.CellTemplate = (DataTemplate)FindResource("SEI_Template"); 
      // for now show only the 5 first elements 
      col.Visibility = i >= 5 ? Visibility.Hidden : Visibility.Visible; 
      grdSch.Columns.Add(col); 
     } 
    } 

여기 (의 일부) 내 XAML이다. 현재 바인딩 (예 : "{Binding Path=data[0].emplName}")은 속성의 첫 번째 항목에 대해 작동합니다. 내가 "{Binding Path=data[1].emplName}"으로 변경하면 두 번째 것과 바인딩됩니다. 그러나 이것은 내가 물론 필요로하는 것이 아닙니다. 같은 바인딩을 바꿀 수있는 방법이 있나요? "{Binding Path=data[Grid.ColumnIndex-1].emplName}"? "매개 변수가있는 바인딩"등에 대한 게시물을 검색하고 발견했지만 매우 분명하거나 직설적 인 것을 발견하지 못했습니다. 물론 나는 멍청한 방법으로 가서 xaml (인덱스 된 속성의 인덱스에서만 다름)에 30 개의 유사한 템플릿을 추가 할 수 있습니다 - 그리고 이것은 확실히 작동 할 것이지만 더 나은 방법으로 만들고 있습니다.

누군가 도와 줄 수 있습니까?

답변

1

하나의 솔루션은 우리가 셀 내용을 결합하는 데 사용할 추가 Binding 속성을 노출 (DataGridTemplateColumn에서 파생) 사용자 정의 열 유형을 만드는 것입니다 사전에 감사합니다.

private void Page_Loaded(object sender, RoutedEventArgs e) 
{ 
    var col = new DataGridTemplateColumn 
    { 
     Header = "Shift", 
     CellTemplate = (DataTemplate)FindResource("SPI_Template") 
    }; 
    grdSch.Columns.Add(col); 
    for (int i = 0; i < 30; i++) 
    { 
     col = new DataGridBoundColumn 
     { 
      Header = "Employee " + (i + 1), 
      Binding = new Binding($"data[{i}]"), 
      Width = 100, 
      CellTemplate = (DataTemplate)FindResource("SEI_Template"), 
     }; 
     grdSch.Columns.Add(col); 
    } 
} 

마지막으로는, 우리의 생성 된 컬럼이 이미 data[i]를 표시하기 때문에, 우리는 그에 따라 SEI_Template을 수정해야합니다 :

public class DataGridBoundColumn : DataGridTemplateColumn 
{ 
    public BindingBase Binding { get; set; } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     var element = base.GenerateEditingElement(cell, dataItem); 
     if (element != null && Binding != null) 
      element.SetBinding(ContentPresenter.ContentProperty, Binding); 
     return element; 
    } 

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     var element = base.GenerateElement(cell, dataItem); 
     if (element != null && Binding != null) 
      element.SetBinding(ContentPresenter.ContentProperty, Binding); 
     return element; 
    } 
} 

우리가 약간 열 생성 코드를 수정해야 그리고 다음은 열 코드는

<DataTemplate x:Key="SEI_Template"> 
    <StackPanel> 
     <TextBlock Text="{Binding emplName}" /> 
     <TextBlock Text="{Binding shftDate}" /> 
    </StackPanel> 
</DataTemplate> 
+0

많은, 많은 감사! 제안한대로 코드가 변경되어 작동합니다. 따라서 기본적으로 xaml의 바인딩을 인덱싱 된 요소로 설정하는 대신 인덱싱 된 속성의 각 항목에 직접 셀을 바인딩합니다. 이것은 내가 쫓아 온 것이었지만 당신의 솔루션은 효과가 있었기 때문에 대단히 괜찮습니다. 다시 한 번 감사드립니다! –

관련 문제