2010-10-19 4 views
3

J'ai une classe de fichier défini comme suitWPF: liaison à une liste dans une classe

public class File 
{ 
public string FileName {set;get;} 
public List<Property> PropertyList; 
} 

Voici comment la classe de propriété ressemble à:

public class Property 
{ 
public string PropertyName { set; get;}; 
public string PropertyValue { set; get;}; 
... 
} 

je dois lier un List<File> à un DataGrid, affiche FileName. En outre, je souhaite créer une colonne pour chaque Property dans les PropertyList, avec la valeur de chaîne de PropertyName comme titre de colonne et la valeur de chaîne de PropertyValue comme valeur de la colonne.

Est-ce possible dans WPF?

Merci,

+1

Espérons que vos noms de classe réelle ne sont pas du fichier et de la propriété ... –

Répondre

1

juste eu à essayer un, problème étrange, mais drôle :-) Nous avons réussi à le faire fonctionner en utilisant ce qui suit. Désolé pour la réponse longue, probablement moyen de détaillée :-)

Tout d'abord, le DataGrid. Clair et simple

<DataGrid Name="c_dataGrid" AutoGenerateColumns="False" 
      CanUserAddRows="False" CanUserDeleteRows="False"/> 

alors la classe de fichier, nommé MyFile

public class MyFile 
{ 
    public MyFile() : this(string.Empty) {} 
    public MyFile(string fileName) 
    { 
     FileName = fileName; 
     MyPropertyList = new ObservableCollection<MyProperty>(); 
    } 

    public string FileName 
    { 
     set; 
     get; 
    } 
    public ObservableCollection<MyProperty> MyPropertyList 
    { 
     get; 
     set; 
    } 
} 

classe de propriété, nommée MyProperty

public class MyProperty 
{ 
    public MyProperty() : this(string.Empty, string.Empty) {} 
    public MyProperty(string propertyName, string propertyValue) 
    { 
     MyPropertyName = propertyName; 
     MyPropertyValue = propertyValue; 
    } 
    public string MyPropertyName 
    { 
     set; 
     get; 
    } 
    public string MyPropertyValue 
    { 
     set; 
     get; 
    } 
} 

Une liste contenant MyFiles

public ObservableCollection<MyFile> MyFileList{ get; set; } 

Créé un peu factice données à popula te la liste et régler la ItemsSource sur le DataGrid

MyFile myFile1 = new MyFile("MyFile1"); 
myFile1.MyPropertyList.Add(new MyProperty("Name1", "Value1")); 
myFile1.MyPropertyList.Add(new MyProperty("Name2", "Value2")); 
myFile1.MyPropertyList.Add(new MyProperty("Name3", "Value3")); 
MyFile myFile2 = new MyFile("MyFile2"); 
myFile2.MyPropertyList.Add(new MyProperty("Name1", "Value1")); 
myFile2.MyPropertyList.Add(new MyProperty("Name4", "Value4")); 
myFile2.MyPropertyList.Add(new MyProperty("Name5", "Value5")); 
MyFileList = new ObservableCollection<MyFile>(); 
MyFileList.Add(myFile1); 
MyFileList.Add(myFile2); 
c_dataGrid.ItemsSource = MyFileList; 

Ajout d'une DataGridTextColumn pour l'attribut FileName

c_dataGrid.Columns.Add(GetNewMyFileNameColumn()); 

private DataGridColumn GetNewMyFileNameColumn() 
{ 
    DataGridTextColumn myFileNameColumn = new DataGridTextColumn(); 
    myFileNameColumn.Header = "FileName"; 
    myFileNameColumn.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto); 

    Binding valueBinding = new Binding(); 
    valueBinding.Path = new PropertyPath("FileName"); 
    valueBinding.Mode = BindingMode.TwoWay; 
    valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
    valueBinding.NotifyOnSourceUpdated = true; 
    valueBinding.NotifyOnTargetUpdated = true; 

    myFileNameColumn.Binding = valueBinding; 

    return myFileNameColumn; 
} 

Et puis pour le MyPropertyList. Je ne voulais ajouter chaque fois myPropertyName si je donne les résultats suivants
MyFile1
-Name1
-Name2
-Name3
monfich2
-Name1
-Name4
-Name5
les colonnes générées en être Name1, Name2, Name3, Name4 et Name5.

foreach (MyFile myFile in MyFileList) 
{ 
    foreach (MyProperty myProperty in myFile.MyPropertyList) 
    { 
     if (ColumnAlreadyAdded(myProperty.MyPropertyName) == false) 
     { 
      c_dataGrid.Columns.Add(GetNewMyPropertyColumn(myProperty.MyPropertyName)); 
     } 
    } 
} 

private bool ColumnAlreadyAdded(string myPropertyName) 
{ 
    foreach (DataGridColumn dataGridColumn in c_dataGrid.Columns) 
    { 
     if (dataGridColumn.Header.ToString() == myPropertyName) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

private DataGridColumn GetNewMyPropertyColumn(string myPropertyName) 
{ 
    DataGridTextColumn myFileNameColumn = new DataGridTextColumn(); 
    myFileNameColumn.Header = myPropertyName; 
    myFileNameColumn.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto); 

    Binding valueBinding = new Binding(); 
    valueBinding.Path = new PropertyPath("MyPropertyList"); 
    valueBinding.Converter = new MyPropertyConverter(myPropertyName); 
    valueBinding.Mode = BindingMode.TwoWay; 
    valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
    valueBinding.NotifyOnSourceUpdated = true; 
    valueBinding.NotifyOnTargetUpdated = true; 

    myFileNameColumn.Binding = valueBinding; 

    return myFileNameColumn; 
} 

j'ai dû alimenter le myPropertyName au constructeur du convertisseur de sorte qu'il sache quelle propriété rechercher.
Et enfin, le convertisseur

public class MyPropertyConverter : IValueConverter 
{ 
    private string m_propertyName = string.Empty; 
    ObservableCollection<MyProperty> m_myPropertyList = null; 

    public MyPropertyConverter(string propertyName) 
    { 
     m_propertyName = propertyName; 
    } 

    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     m_myPropertyList = value as ObservableCollection<MyProperty>; 
     if (m_myPropertyList == null) 
     { 
      return null; 
     } 
     foreach (MyProperty myProperty in m_myPropertyList) 
     { 
      if (myProperty.MyPropertyName == m_propertyName) 
      { 
       return myProperty.MyPropertyValue; 
      } 
     } 
     return null; 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (m_myPropertyList != null) 
     { 
      foreach (MyProperty myProperty in m_myPropertyList) 
      { 
       if (myProperty.MyPropertyName == m_propertyName) 
       { 
        myProperty.MyPropertyValue = value.ToString(); 
        break; 
       } 
      } 
     } 
     return m_myPropertyList; 
    } 
} 

Dans le convertissons vérifiera la myPropertyName donnée et si elle le trouve, retourner le MyPropertyValue, sinon nulle. Il en va de même pour la méthode ConvertBack, mais elle définira MyPropertyValue à la nouvelle valeur de MyProperty avec le MyPropertyName donné, puis retournera la liste qui est soit une liste soit null.

Les propriétés qui ne sont pas dans une liste MyFile ne seront pas éditables, elles reviendront juste à zéro en quittant la cellule (ce qui est probablement le point).

Cela entraînera un DataGrid qui ressemble à ceci.

alt text

+0

c'est génial, merci. – sean717

Questions connexes