2010-01-29 5 views
5

WPF에서 DataGrid를 바인딩하는 데이터에 대한 질문이 있습니다. 나는 그것이 거의 같다고 생각하지만 툴킷이 아닌 자체 DataGrid를 가진 VS 2010 Beta 2를 사용하고 있습니다.WPF DataGridCell 템플릿의 동적 바인딩

일년 중 매주 한 번씩 52 개의 열이있는 데이터 집합에 바인딩하고 싶습니다. 이러한 이유로 각 필드를 지정하는 대신 동적으로 데이터를 바인딩하려고합니다. 각 필드의 값은 일부 조건에 따라 true 또는 false입니다. 이 값을 기반으로 조건이 참일 경우 셀 템플릿에 이미지를 표시하고 조건이 참이 아니면 숨길 수 있습니다.

내 문제는 내가 찾은 템플릿을 사용하는 모든 예제는 고정 된 미리 정의 된 필드의 경우를 말합니다. 여기서 텍스트 = "{바인딩 사용자 이름}"과 같은 바인딩을 사용할 수 있습니다. 디자인 타임에 필드 이름이 무엇인지 알지 못하기 때문에 나에게 좋지 않습니다.

나는이 문제를 보여주는 간단한 예를 구성했다. 이 예제에서 true 및 false 값을 포함하는 데이터 테이블이 생성됩니다. 내 템플릿의 이미지가 보이지 않습니다. 데이터의 참 또는 거짓 값에 따라 어떻게 보이지 않게 할 수 있습니까? 뒤에

<Window.Resources> 

    <!--This is the bit that doesn't work...--> 
    <Style TargetType="{x:Type Image}" x:Key="HideWhenFalse"> 
     <Setter Property="Visibility" Value="Hidden" /> 
     <Style.Triggers> 
      <DataTrigger 
     Binding="{Binding Path=???}" 
     Value="True"> <!--What to put for the path? --> 
       <Setter Property="Visibility"> 
        <Setter.Value> 
         Visible 
        </Setter.Value> 
       </Setter> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    <!--Up to here--> 

    <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <StackPanel> 
         <Image Source="Images/tick.bmp" Style="{StaticResource HideWhenFalse}"> 

         </Image> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<Grid> 
    <DataGrid 
     x:Name="myDataGrid" 
     AutoGenerateColumns="True" > 

    </DataGrid> 
</Grid> 

코드 :

공공 부분 클래스 MainWindow를 : 윈도우 {

public MainWindow() 
{ 
    InitializeComponent(); 

    DataTable dtTable = new DataTable(); 

    dtTable.Columns.Add("A", typeof(Boolean)); 
    dtTable.Columns.Add("B", typeof(Boolean)); 
    dtTable.Columns.Add("C", typeof(Boolean)); 
    dtTable.Columns.Add("D", typeof(Boolean)); 
    dtTable.Columns.Add("E", typeof(Boolean)); 
    dtTable.Columns.Add("F", typeof(Boolean)); 

    for (int i = 0; i < 5; i++) 
    { 
     object[] oValues = new Object[dtTable.Columns.Count]; 

     for (int j = 0; j < dtTable.Columns.Count; j++) 
     { 
      oValues[j] = (j % 2 == 1) ? true : false; 
     } 

     dtTable.Rows.Add(oValues); 
    } 

    myDataGrid.ItemsSource = dtTable.DefaultView; 
    myDataGrid.Items.Refresh(); 
} 

}

주의 이것은 아마도 명백하며 나는 완전히 잘못된 방식으로 문제에 접근하고있다. 여기에 자백이 있습니다. 저는 몇 달 동안 WPF에서 머리를 쓰려고 노력해 왔지만 여전히 모든 문제에 대해 잘못된 방향으로 접근하고있는 것 같습니다. 나는 페니가 곧 떨어지기를 바란다.

답변

9

MultiBinding을 사용할 수 있습니다. 첫 번째 바인딩은 셀에서 실제 데이터 컨텍스트 (행이 됨)를 취하고 두 번째 바인딩은 열을 가져옵니다. 거기에서 셀 값을 검색 할 수 있습니다.

변환기 코드 :

public class RowColumnToCellConverter : IMultiValueConverter { 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { 
     DataRowView row = values[0] as DataRowView; 
     DataGridColumn column = values[1] as DataGridColumn; 
     return row != null && column != null 
      ? row[column.SortMemberPath] 
      : DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { 
     throw new NotSupportedException(); 
    } 
} 

XAML :

<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <StackPanel> 
         <TextBlock x:Name="TextOK" Text="OK" Visibility="Collapsed" /> 
        </StackPanel> 
        <ControlTemplate.Triggers> 
         <DataTrigger Value="True"> 
          <DataTrigger.Binding> 
           <MultiBinding Converter="{StaticResource RowColumnToCellConverter}"> 
            <Binding /> 
            <Binding RelativeSource="{x:Static RelativeSource.Self}" Path="Column" /> 
           </MultiBinding> 
          </DataTrigger.Binding> 
          <Setter TargetName="TextOK" Property="Visibility" Value="Visible" /> 
         </DataTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

내가 테스트를 위해 TextBlock 대신 이미지를 사용하지만 코드가 동일합니다. DataGridCell의 스타일로 직접 할 수 있다면 이미지 스타일을 정의하지 마십시오.

+0

매우 빠른 답변 주셔서 감사합니다. 줄리앙. 그것은 대접을합니다. – Richard

+1

@ 리차드 -이 대답을 받아 들여야합니다 – David

+0

merci bien, ça m'a beaucoup aidé! – David

관련 문제