2016-11-23 13 views
-1

mvvmを使用して動的にデータグリッドを生成したいとします。データグリッドの各セルでは、私はオブジェクトを表示する必要があります。列名は、オブジェクトのプロパティの1つです。データグリッドのItemsourceはオブジェクトのリストになります。 mvvmを使って動的にDataGridを生成するには?mvvmを使用してwpfデータグリッドでカラムを動的に生成する方法

更新

私がICustomTypeDescriptorをusiing拡張されているカスタムクラスを作成しました。

public class MyCustomType : ICustomTypeDescriptor 
    { 
    // This is instance data. 
    private readonly BindingList<PropertyDescriptor> _propertyDescriptors = new BindingList<PropertyDescriptor>(); 

    // The data is stored on the type instance. 
    private readonly IDictionary<string, object> _propertyValues = new Dictionary<string, object>(); 

    // The property descriptor now takes an extra argument. 
    public void AddProperty(string name, Type type) 
    { 
     _propertyDescriptors.Add(new MyPropertyDescriptor(name, type)); 
    } 

    public PropertyDescriptorCollection GetProperties() 
    { 
     return new PropertyDescriptorCollection(_propertyDescriptors.ToArray()); 
    } 

    public PropertyDescriptorCollection GetProperties(Type type) 
    { 
     return new PropertyDescriptorCollection(_propertyDescriptors.ToArray()); 
    } 

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
    { 
     return GetProperties(); 
    } 

    public object GetPropertyOwner(PropertyDescriptor pd) 
    { 
     throw new NotImplementedException(); 
    } 

    public AttributeCollection GetAttributes() 
    { 
     throw new NotImplementedException(); 
    } 

    public string GetClassName() 
    { 
     throw new NotImplementedException(); 
    } 

    public string GetComponentName() 
    { 
     throw new NotImplementedException(); 
    } 

    public TypeConverter GetConverter() 
    { 
     throw new NotImplementedException(); 
    } 

    public EventDescriptor GetDefaultEvent() 
    { 
     throw new NotImplementedException(); 
    } 

    public PropertyDescriptor GetDefaultProperty() 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetEditor(Type editorBaseType) 
    { 
     throw new NotImplementedException(); 
    } 

    public EventDescriptorCollection GetEvents() 
    { 
     return null; 
    } 

    public EventDescriptorCollection GetEvents(Attribute[] attributes) 
    { 
     return null; 
    } 

    private class MyPropertyDescriptor : PropertyDescriptor 
    { 
     // This data is here to indicate that different instances of the type 
     // object may have properties of the same name, but with different 
     // characteristics. 
     private readonly Type _type; 

     public MyPropertyDescriptor(string name, Type type) 
      : base(name, null) 
     { 
      _type = type; 
     } 

     public override bool CanResetValue(object component) 
     { 
      throw new NotImplementedException(); 
     } 

     public override Type ComponentType 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public override object GetValue(object component) 
     { 
      MyCustomType obj = (MyCustomType) component; 
      object value = null; 
      obj._propertyValues.TryGetValue(Name, out value); 
      return value; 
     } 

     public override bool IsReadOnly 
     { 
      get { return false; } 
     } 

     public override Type PropertyType 
     { 
      get { return _type; } 
     } 

     public override void ResetValue(object component) 
     { 
      throw new NotImplementedException(); 
     } 

     public override void SetValue(object component, object value) 
     { 
      var oldValue = GetValue(component); 

      if (oldValue != value) 
      { 
       MyCustomType obj = (MyCustomType) component; 
       obj._propertyValues[Name] = value; 
       OnValueChanged(component, new PropertyChangedEventArgs(Name)); 
      } 
     } 

     public override bool ShouldSerializeValue(object component) 
     { 
      throw new NotImplementedException(); 
     } 

     public override void AddValueChanged(object component, EventHandler handler) 
     { 
      // set a breakpoint here to see WPF attaching a value changed handler 
      base.AddValueChanged(component, handler); 
     } 
    } 
} 

このカスタムタイプオブジェクトのリストをdatagrid itemsourceにバインドします。しかし、DataGridはコンテンツを表示していませんか?

答えて

0

DataGridを使用する方法は、ItemsSourceとしてIEnumerable<T>を使用します.Tは、列を生成するプロパティを持つクラスまたはインターフェイスです。 DataGridがサポートする型を使用する必要があります。ほとんどの値型がサポートされています。サポートされているタイプと使用方法については、リストHEREがあります。

リストには、セルではなく行のオブジェクトが含まれている必要があります。セルは、リストの汎用引数の型の各パブリックプロパティに対して、DataGridによって自動的に生成されます。

次のようにあなたは、リストをバインドするためにMVVMを使用することができます。

<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="True"></DataGrid> 

確かに、データグリッドのデータコンテキスト(継承または明示的に)アイテムをpublic IEnumerable<T> MyList { get; }を含める必要があります。

UPDATEは実際に順番に各列オブジェクトは、細胞のためのオブジェクトのリストを有しています。 各セルオブジェクトには複数のプロパティがあります。私は列名として プロパティ値の1を表示すると、各セルオブジェクトは、オブジェクトの種類に基づいて異なる セルスタイルを持っています。どのように動的に多くの条件を持つこれらのデータグリッド を作成するには?

WPFでは、DataGridにはすべての行に対して同じ列が設定されています。つまり、各セルに異なる列データを定義しても、最初の行(または必要な列)だけを使用して列を定義することができます。私はむしろ、動的ではない宣言的な情報であるため(行から行または時々刻々と変更するべきではない)、列プロパティ(データ型、ヘッダーなど)を宣言するためにCustom Attributesを作成することを提案します。スタイル情報は、THISスレッドで説明されているようなトリガを使用することによって、まだいくらかのダイナミズムを持つことができます。これはWPFのより多くの方法です。

とにかく、スキーマを守りたい場合は、DataGridから派生したクラスに列探索ロジックを実装する必要があります。 ItemsSourceChangedハンドラでは、ItemsSourceのタイプをチェックします。これがIEnumerableの場合、リフレクトでジェネリック引数(T)を取得し、そのタイプがスキーマを記述するカラムをサポートしているかどうかをチェックします。次のようなものがあります。

protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue) 
{ 
    base.OnItemsSourceChanged(oldValue, newValue); 

    if (AutoGenerateColumns && newValue != null && newValue.GetType().IsGenericType) 
    { 
     this.Columns.Clear(); 

     var type = newValue.GetType().GetGenericArguments().First(); 

     if (typeof(IMyColumnDescriptionStructure).IsAssignableFrom(type)) 
     { 
      var rows = newValue as IEnumerable<IMyColumnDescriptionStructure>; 
      var firstRow = rows.First() as IMyColumnDescriptionStructure; 

      // TODO: explore your structure and add column definitions 
      ///this.Columns.Add(...) 
     } 
    } 
} 
+0

ありがとうございましたDaniel、実際には、各行オブジェクトには、セルのオブジェクトのリストがあります。各セルオブジェクトには複数のプロパティがあります。私は列名としてプロパティ値の1を表示したいと思い、各セルオブジェクトは、オブジェクトのタイプに基づいて異なるセルスタイルを持っています。どのようにこれらの多くの条件でデータグリッドを動的に作成するのですか? – Rony

関連する問題