2017-02-28 1 views
1

전자 구성 요소의 재고를 관리하기 위해 WPF 소프트웨어를 구축하고 있습니다.개체 유형 및 하위 유형을 기반으로하는 WPF DataGrid 동적 열

나는 다음과 같은 구조를 가지고 :

public class Part 
{ 
    public string Manufacturer { get; set; } 
    public string PartNumber { get; set; } 
} 
public class Resistor : Part 
{ 
    public string Resistance { get; set;} 
    public string Power { get; set;} 
} 
public class Capacitor : Part 
{ 
    public string Capacitance { get; set; } 
    public string Voltage { get; set; } 
} 

저항과 콘덴서는 파트의 서브 타입이다.

저는 DataGridObservableCollection<Part>에 바인딩하고 ListCollectionView을 사용하여 필터링 및 그룹화 기능을 추가했습니다. 나는 단지 Resistor 하위 유형을 얻기 위해 ListCollectionView를 필터링 할 때

내가 달성하기 위해 노력하고있어 것은, 나는 DataGrid 그것이 Resistor 유형의 속성을 보여주기 위해 열을의 업데이트 할하고 기본 클래스 Part이다 (그래서를 얻을 것 열 제조업체, 부품 번호, 저항 및 전력). 동시에 ListCollectionView을 필터링하여 Capacitor 하위 유형을 가져 오는 경우 DataGridCapacitor 클래스 공용 속성과 Part 공용 속성 (제조업체, 부품 번호, 커패시턴스 및 전압)을 가져야합니다. 마지막으로 필터링을 적용하지 않으면 DataGridPart 속성 (제조업체 및 부품 번호) 만 표시됩니다. 난 단지 Resistors을 위해 ListCollectionView를 필터링 할 경우에도,

은 내가 AutoGenerateColumns=true을 사용하려고하지만 DataGridPart 특성을 보여줍니다. 또한 ObservableCollection의 유형을 dynamic으로 변경하려고 시도했지만 작동하지 않았습니다.

DataGrid 열을 ObservableCollection에 포함 된 개체의 유형에 따라 어떻게 변경할 수 있습니까?

답변

1

다음은 자동 생성 기능을 사용하는 솔루션입니다. 관측 가능한 컬렉션에 ITypedList 인터페이스를 구현하기 만하면됩니다 ...

public class Parts : ObservableCollection<Part>, ITypedList 
{ 
    public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) 
    { 
     if(Count == 0) 
     { 
      return TypeDescriptor.GetProperties(typeof(Part)); 
     } 
     else 
     { 
      PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this[0]); 
      return pdc; 
     } 
    } 

    public string GetListName(PropertyDescriptor[] listAccessors) 
    { 
     return "Parts"; 
    } 
} 
+0

이 기능은 작동하지만 GetItemProperties는 응용 프로그램을 불러올 때만 호출됩니다.필터링이 ObservableCollection에서 가져온 ListViewCollection에 적용될 때마다 새로 고쳐야합니다. 이것이 가능한가? – RHaguiuda

+1

예, 그렇지만 매우 우아하지는 않습니다 ... dataGrid.ItemsSource = null; dataGrid.ItemsSource = PartCollection; – AQuirky

+0

감사합니다. 잘된 일. – RHaguiuda

2

여기에이 방법이 있습니다. 열을 자동으로 생성하지 마십시오. 가능한 모든 열을 설정하십시오. 그런 다음 각 열의 가시성을 열이 표시되는지 여부를 결정하는 변환기에 바인딩합니다. 여기

<FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/> 
    <DataGrid x:Name="dataGrid" ItemsSource="{Binding PartCollection}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Manufacturer" Binding="{Binding Manufacturer}"/> 
      <DataGridTextColumn Header="Part Number" Binding="{Binding PartNumber}" /> 
      <DataGridTextColumn Header="Power" Binding="{Binding Power}" Visibility="{Binding DataContext.PartCollection, Source={x:Reference dummyElement}, Converter={StaticResource ColumnVisibility}, ConverterParameter=Resistor}"/> 
      <DataGridTextColumn Header="Resistance" Binding="{Binding Resistance}" Visibility="{Binding DataContext.PartCollection, Source={x:Reference dummyElement}, Converter={StaticResource ColumnVisibility}, ConverterParameter=Resistor}"/> 
      <DataGridTextColumn Header="Capacitance" Binding="{Binding Capacitance}" Visibility="{Binding DataContext.PartCollection, Source={x:Reference dummyElement}, Converter={StaticResource ColumnVisibility}, ConverterParameter=Capacitor}"/> 
      <DataGridTextColumn Header="Voltage" Binding="{Binding Voltage}" Visibility="{Binding DataContext.PartCollection, Source={x:Reference dummyElement}, Converter={StaticResource ColumnVisibility}, ConverterParameter=Capacitor}"/> 
     </DataGrid.Columns> 
    </DataGrid> 

public class ColumnVisibilityConverter : IValueConverter 
    { 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     ObservableCollection<Part> collection = value as ObservableCollection<Part>; 
     string collectionType = parameter as string; 
     if(collection != null && collectionType != null && collection.Count > 0) 
     { 
      switch(collectionType) 
      { 
       case "Resistor": return collection[0].GetType() == typeof(Resistor) ? Visibility.Visible : Visibility.Hidden; 
       case "Capacitor": return collection[0].GetType() == typeof(Capacitor) ? Visibility.Visible : Visibility.Hidden; 
       default: return Visibility.Hidden; 
      } 
     } 
     return Visibility.Hidden; 
    } 

가 I 데이터 그리드 가시성을 결합하여 약간 고전 ... 여기
<Window.Resources> 
    <local:ColumnVisibilityConverter x:Key="ColumnVisibility"/> 
</Window.Resources> 

는 변환기 ... 변환기에 대한 고정 자원 기둥. 여기에 답변을 찾았습니다. Binding Visibility for DataGridColumn in WPF

수동으로 열을 설정하는 것이 가장 좋습니다. 정말로 자동 생성하려는 경우이를 수행하는 또 다른 방법이 있습니다. 컬렉션에 ICustomTypeDescriptor를 구현하여 컬렉션에 포함 된 파생 된 형식의 속성에 대한 PropertyDescriptors를 반환 할 수 있습니다.

+0

저는 부울 속성을 만들고 해당 속성에 열 가시성을 바인딩하기 위해 여러분의 아이디어를 사용했습니다. 일했다! – RHaguiuda