2016-08-04 11 views
2

Voraussetzungen gezeigt: .Net Framework 4.5.1Anzeigenamen der dynamischen Datagrid-Spalten werden nicht

Ich ITypedList und ICustomTypeDescriptor mit Spalten dynamisch machen DataGrid zu erzeugen. Um benutzerfreundliche Spaltennamen bereitzustellen, erstelle ich Eigenschaftsdeskriptoren, die den Konstruktor DisplayNameAttribute bereitstellen, wie im folgenden Beispiel gezeigt. Obwohl Debugger zeigt, dass PropertyDescriptor.DisplayName Eigenschaft erhält, was ich in dem Attribut DataGrid zur Verfügung gestellt wird, berücksichtigt diesen Wert nicht und zeigt weiterhin den Eigenschaftsnamen anstelle der Eigenschaft Anzeige Name. Irgendwelche Ideen, was ich falsch mache?

Beispiel WDataGridTest.xaml

<Window x:Class="Local.WGridViewTest" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:l="clr-namespace:Local" 
     Title="WGridViewTest" Height="300" Width="300"> 
    <Window.Resources> 
     <l:DataTable x:Key="DataTable"/> 
    </Window.Resources> 
    <Grid> 
     <DataGrid ItemsSource="{StaticResource ResourceKey=DataTable}"/> 
    </Grid> 
</Window> 

-Code hinter WDataGridTest.xaml.cs

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Windows; 
using System.ComponentModel; 

namespace Local { 
    /// <summary>Interaction logic for WGridViewTest.xaml</summary> 
    public partial class WGridViewTest : Window { 
     public WGridViewTest() { 
      InitializeComponent(); 
     } 
    } 

    public class DataTable : BindingList<DataRow>, ITypedList { 
     private PropertyDescriptorCollection _PropertyDescriptors; 

     public DataTable() : 
      base() { 
      AllowNew = false; 
      AllowRemove = false; 
      AllowEdit = true; 
      _PropertyDescriptors = new PropertyDescriptorCollection(new PropertyDescriptor[0], false); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column1")); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column2")); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column3")); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
     } 

     #region ITypedList implementation 
     public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] ListAccessors) { 
      return _PropertyDescriptors; 
     } 
     public string GetListName(PropertyDescriptor[] ListAccessors) { 
      return "Data Table"; 
     } 
     #endregion ITypedList implementation 
    } 

    public class DataRow : ICustomTypeDescriptor { 
     public DataRow(DataTable DataTable) { 
      this.DataTable = DataTable; 
     } 

     public DataTable DataTable { 
      get; 
      private set; 
     } 

     public object GetValue(string ColumnName) { 
      return String.Concat(ColumnName, "@", GetHashCode()); 
     } 

     public void SetValue(string ColumnName, object Value) { 
     } 

     #region ICustomTypeDescriptor implementation 
     public AttributeCollection GetAttributes() { return AttributeCollection.Empty; } 
     public string GetClassName() { return GetType().FullName; } 
     public string GetComponentName() { return GetType().Name; } 
     public TypeConverter GetConverter() { return null; } 
     public EventDescriptor GetDefaultEvent() { return null; } 
     public PropertyDescriptor GetDefaultProperty() { return null; } 
     public object GetEditor(Type EditorBaseType) { return null; } 
     public EventDescriptorCollection GetEvents(Attribute[] Attributes) { return EventDescriptorCollection.Empty; } 
     public EventDescriptorCollection GetEvents() { return EventDescriptorCollection.Empty; } 
     public PropertyDescriptorCollection GetProperties(Attribute[] Attributes) { return DataTable.GetItemProperties(null); } 
     public PropertyDescriptorCollection GetProperties() { return DataTable.GetItemProperties(null); } 
     public object GetPropertyOwner(PropertyDescriptor PropertyDescriptor) { return this; } 
     #endregion Property value tracking 
    } 

    public class DataValuePropertyDescriptor : PropertyDescriptor { 
     public DataValuePropertyDescriptor(string Name) : 
      base(Name, new Attribute[] { new DisplayNameAttribute(String.Concat("Display: ", Name)) }) { 
     } 

     #region PropertyDescriptor implementation 
     public override Type ComponentType { get { return typeof(DataRow); } } 
     public override Type PropertyType { get { return typeof(string); } } 
     public override bool IsReadOnly { get { return false; } } 
     public override bool CanResetValue(object DataRow) { return true; } 
     public override object GetValue(object DataRow) { return ((DataRow)DataRow).GetValue(Name); } 
     public override void ResetValue(object DataRow) { ((DataRow)DataRow).SetValue(Name, null); } 
     public override void SetValue(object DataRow, object Value) { ((DataRow)DataRow).SetValue(Name, Value); } 
     public override bool ShouldSerializeValue(object DataRow) { return false; } 
     #endregion PropertyDescriptor implementation 
    } 
} 

Und das Ergebnis sieht wie folgt aus.
enter image description here

+0

funktioniert für mich mit 4.0 – jHilscher

+0

@jHilscher fein, versuchte 4.0, gleiche Ergebnisse sehen, keine Anzeigenamen. Hast du mein Beispiel getestet oder funktioniert dein Code? –

+0

Ich habe nur Ihre Probe kopiert/eingefügt. – jHilscher

Antwort

0

Nachdem ich dieses Beispiel an mehreren anderen Konfigurationen mit den gleichen Ergebnissen versucht habe, habe ich die Standardspaltenvorlage wie folgt überschrieben. Nur für den Fall, dass jemand dieses Problem auch sehen sollte, ist dies die Problemumgehung, obwohl man daran denken sollte, dass es zu Aero-Thema passt, da es kein Aero2 auf Windows 7 gibt. Wenn Sie Windows 7 nicht unterstützen müssen, ersetzen Sie Aero einfach mit aero2 verweist auf die entsprechende Assembly in Ihrem Projekt.

WDataGridTest.xaml

<Window x:Class="Local.WDataGridTest" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:Local" 
     xmlns:data="clr-namespace:System.Data;assembly=System.Data" 
     xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
     Title="WGridViewTest" Height="300" Width="300"> 
    <Window.Resources> 
     <local:DataTable x:Key="DataTable"/> 
     <local:DataColumnDisplayNameConverter x:Key="DataColumnDisplayNameConverter"/> 
     <Style x:Key="DataGridColumnHeaderGripperStyle" TargetType="{x:Type Thumb}"> 
      <Setter Property="Width" Value="8"/> 
      <Setter Property="Background" Value="Transparent"/> 
      <Setter Property="Cursor" Value="SizeWE"/> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Thumb}"> 
         <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}"> 
      <Setter Property="VerticalContentAlignment" Value="Center"/> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}"> 
         <Grid> 
          <themes:DataGridHeaderBorder BorderBrush="{TemplateBinding BorderBrush}" 
                 BorderThickness="{TemplateBinding BorderThickness}" 
                 Background="{TemplateBinding Background}" 
                 IsClickable="{TemplateBinding CanUserSort}" 
                 IsPressed="{TemplateBinding IsPressed}" 
                 IsHovered="{TemplateBinding IsMouseOver}" 
                 Padding="{TemplateBinding Padding}" 
                 SortDirection="{TemplateBinding SortDirection}" 
                 SeparatorBrush="{TemplateBinding SeparatorBrush}" 
                 SeparatorVisibility="{TemplateBinding SeparatorVisibility}"> 
           <TextBlock HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              TextAlignment="Center" 
              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
              Text="{Binding Converter={StaticResource ResourceKey=DataColumnDisplayNameConverter}, ConverterParameter={StaticResource ResourceKey=DataTable}}" 
              TextWrapping="Wrap"/> 
          </themes:DataGridHeaderBorder> 
          <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource DataGridColumnHeaderGripperStyle}"/> 
          <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource DataGridColumnHeaderGripperStyle}"/> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <DataGrid ItemsSource="{Binding Source={StaticResource ResourceKey=DataTable}}" ColumnHeaderStyle="{StaticResource ResourceKey=DataGridColumnHeaderStyle}"/> 
    </Grid> 
</Window> 

-Code hinter WDataGridTest.xaml.cs

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Data; 
using System.Globalization; 
using System.ComponentModel; 

namespace Local { 
    /// <summary>Interaction logic for WDataGridTest.xaml</summary> 
    public partial class WDataGridTest : Window { 
     public WDataGridTest() { 
      InitializeComponent(); 
     } 
    } 

    public class DataTable : BindingList<DataRow>, ITypedList { 
     private PropertyDescriptorCollection _PropertyDescriptors; 

     public DataTable() : 
      base() { 
      AllowNew = false; 
      AllowRemove = false; 
      AllowEdit = true; 
      _PropertyDescriptors = new PropertyDescriptorCollection(new PropertyDescriptor[0], false); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column1")); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column1")); 
      _PropertyDescriptors.Add(new DataValuePropertyDescriptor("Column1")); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
      Items.Add(new DataRow(this)); 
     } 

     #region ITypedList implementation 
     public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] ListAccessors) { 
      return _PropertyDescriptors; 
     } 
     public string GetListName(PropertyDescriptor[] ListAccessors) { 
      return "Data Table"; 
     } 
     #endregion ITypedList implementation 
    } 

    public class DataRow : ICustomTypeDescriptor { 
     public DataRow(DataTable DataTable) { 
      this.DataTable = DataTable; 
     } 

     public DataTable DataTable { 
      get; 
      private set; 
     } 

     public object GetValue(string ColumnName) { 
      return string.Concat(ColumnName, "@", GetHashCode()); 
     } 

     public void SetValue(string ColumnName, object Value) { 
     } 

     #region ICustomTypeDescriptor implementation 
     public AttributeCollection GetAttributes() { return AttributeCollection.Empty; } 
     public string GetClassName() { return GetType().FullName; } 
     public string GetComponentName() { return GetType().Name; } 
     public TypeConverter GetConverter() { return null; } 
     public EventDescriptor GetDefaultEvent() { return null; } 
     public PropertyDescriptor GetDefaultProperty() { return null; } 
     public object GetEditor(Type EditorBaseType) { return null; } 
     public EventDescriptorCollection GetEvents(Attribute[] Attributes) { return EventDescriptorCollection.Empty; } 
     public EventDescriptorCollection GetEvents() { return EventDescriptorCollection.Empty; } 
     public PropertyDescriptorCollection GetProperties(Attribute[] Attributes) { return DataTable.GetItemProperties(null); } 
     public PropertyDescriptorCollection GetProperties() { return DataTable.GetItemProperties(null); } 
     public object GetPropertyOwner(PropertyDescriptor PropertyDescriptor) { return this; } 
     #endregion Property value tracking 
    } 

    public class DataValuePropertyDescriptor : PropertyDescriptor { 
     public DataValuePropertyDescriptor(string Name) : 
      base(Name, new Attribute[] { new DisplayNameAttribute(string.Concat("Display: ", Name)) }) { 
     } 

     #region PropertyDescriptor implementation 
     public override Type ComponentType { get { return typeof(DataRow); } } 
     public override Type PropertyType { get { return typeof(string); } } 
     public override bool IsReadOnly { get { return false; } } 
     public override bool CanResetValue(object DataRow) { return true; } 
     public override object GetValue(object DataRow) { return ((DataRow)DataRow).GetValue(Name); } 
     public override void ResetValue(object DataRow) { ((DataRow)DataRow).SetValue(Name, null); } 
     public override void SetValue(object DataRow, object Value) { ((DataRow)DataRow).SetValue(Name, Value); } 
     public override bool ShouldSerializeValue(object DataRow) { return false; } 
     #endregion PropertyDescriptor implementation 
    } 

    public class DataColumnDisplayNameConverter : IValueConverter { 
     public DataColumnDisplayNameConverter() 
      : base() { 
     } 

     public object Convert(object Value, Type TargetType, object Parameter, CultureInfo Culture) { 
      DataTable table = (DataTable)Parameter; 
      string property = (string)Value; 
      foreach (PropertyDescriptor descriptor in table.GetItemProperties(null)) { 
       if (property == descriptor.Name) { 
        return descriptor.DisplayName; 
       } 
      } 
      return DependencyProperty.UnsetValue; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
      throw new NotImplementedException(); 
     } 
    } 
}