2012-12-26 17 views
7

Pozwala obraz, który mam następujące klasyDataGridView - Wykorzystanie DataPropertyName pokazać właściwość element podrzędny

public class Master 
{ 
    public string MasterName = "Something"; 

    public List<Detail> details = new List<Detail>(); 
} 

public class Detail 
{ 
    public string Foo = "Test"; 
} 

A potem chcę pokazać kolekcję detali obiektów w DataGridView, korzystając z poniższego

DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn(); 
column.DataPropertyName = "Details.Foo"; 
column.HeaderText = "Foo header"; 

dgv.Columns.Add(column); 
kod

Kolumna jest wyświetlana na siatce, ale bez wartości

+0

Czy na pewno DataPropertyName to, co chcesz? Wygląda na to, że szukasz czegoś więcej na wzór Wartości. Podejrzewam, że nie pracujesz z ASP.Net, co jest mi dobrze znane, ale sprawdziłbym inne właściwości DataGridViewTextBoxColumn, aby sprawdzić, czy jest coś jeszcze, co da ci to, czego potrzebujesz. – Melanie

+0

@Melanie Używam formularzy systemu Windows.Przyjrzę się innym właściwościom. – Andrey

+0

Również, gdy używam własności innego obiektu, jest to w porządku, na przykład: DataPropertyName = "MasterName" – Andrey

Odpowiedz

2

Można zastąpić metodę ToString w dziecku jednostki, dla przykładu:

public class FormulariosENT { 

    #region PROPERTIES 

    public int IdFromulario { get; set; } 
    public string DescripcionFormulario { get; set; } 

    #endregion 

    #region PUBLIC METHODS 
    public override string ToString() { 

     return DescripcionFormulario; 
    } 

Później wiążemy nazwę dziecka podmiotu.

+1

Co z klasą generowaną przez EF? Nie mogę ich zmodyfikować. – Andiana

+0

W takim razie, jak mogę uczynić DescripcionFormulario edytowalnym przez datagrid? – miguelmpn

0

gdzie jest twój datasoure? musisz doprowadzić do źródła. że ją znajdzie. można to zrobić

źródło:

  1. :

    List<Detail> list = new List<Detail>(); 
    for (int i = 0; i < 10; i++) 
    { 
        Detail d = new Detail(); 
        d.Foo = "test"; 
        list.Add(d); 
    } 
    
    this.dgv.DataSource = list; 
    this.dgv.Columns[0].Visible = false; 
    DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn(); 
    dgvc.HeaderText = "列标题"; 
    dgvc.DataPropertyName = "foo"; 
    this.dgv.Columns.Add(dgvc); 
    
  2. :

    public class Detail 
    { 
        private string foo; 
    
        public string Foo 
        { 
         get { return foo; } 
         set { foo = value; } 
        } 
    } 
    
+0

Jak uzyskać to dla podtypu? – miguelmpn

4

W przypadku, gdy chcesz korzystać z wielu elementów podrzędnych tak:

class MyClass 
{ 
    public int Id; 
    public MyOtherClass OtherClass; 
} 

class MyOtherClass 
{ 
    public string Name; 
    public int Number; 
} 

Jak o:

1-ty rozwiązanie wartości ustawić dla każdej komórki w jakimś wydarzeniu (mabye innym jest lepiej) ręcznie po ustawieniu źródła danych, na przykład:

private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    MyClass data = dgv.Rows[ e.RowIndex ].DataBoundItem as MyClass; 

    dgv.Rows[ e.RowIndex ].Cells[ "colName" ].Value = data.OtherClass.Name; 
    dgv.Rows[ e.RowIndex ].Cells[ "colNumber" ].Value = data.OtherClass.Number; 
} 

Drugie rozwiązanie Co ze stworzeniem odpowiedniej DataTable z danych, a następnie związaniem?

Byłbym wdzięczny za wszelkie opinie ;-)

+1

Dobry pomysł, i prawdopodobnie szybko. MSDN ostrzega, że ​​ta funkcja będzie wywoływana dość często i należy unikać długiego przetwarzania. Stąd dwie poprawki: (1) Formatuj tylko komórkę, której żąda parametr e. Funkcja zostanie wywołana raz dla każdej sformatowanej komórki. (2) Zamiast używać łańcuchów dla kolumn, użyj e.ColumnIndex, aby uzyskać dostęp do komórki –

5

Jeśli chcesz być bardziej ogólne (czyli używając DataPropertyName = "MyProp1.MyProp2.MyProp3") można użyć tej

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    DataGridViewColumn column = Grid.Columns[e.ColumnIndex]; 
    if (column.DataPropertyName.Contains(".")) 
    { 
     object data = Grid.Rows[e.RowIndex].DataBoundItem; 
     string[] properties = column.DataPropertyName.Split('.'); 
     for (int i = 0; i < properties.Length && data != null; i++) 
      data = data.GetType().GetProperty(properties[i]).GetValue(data); 
     Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = data; 
    } 
} 
1

Wystarczy to zrobić:

Maskuj właściwość, z której chcesz uzyskać wartość childvalue za pomocą [Browsable (false)], więc nie pojawi się w datagrid. Następnie należy utworzyć nowy obiekt w swojej klasie, która posiada obiekt podrzędny, który ma tylko „dostać” metody wykazujące wartość childproperty: Na przykład:

[Browsable(false)] //Because we use the CreatorUsernameProperty to do this. 
public virtual User Creator { get; set; } 

[DisplayName("Creator")] //shows like this in the grid 
public string CreatorUsername => Creator?.Username; 
Powiązane problemy