• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

WPF - bindowanie kolekcji zawierającej pole i kolekcje do DataGrid

Konkurs Mistrz Programowania
0 głosów
627 wizyt
pytanie zadane 26 marca 2018 w C# przez Wolfer Nowicjusz (120 p.)
edycja 27 marca 2018 przez Wolfer

Witam

Mam pytanie odnośnie bindowania bardziej złożonych kolekcji do kontrolki DataGrid.

Gdy mamy zwykłą listę przechowującą typy wartościowe, to wystarczy podpiąć listę pod właściwość DataContext lub ściślej pod ItemSource. W przypadku list zawierających typy referyncyjne, musimy określić jak właściwości klasy będą bindowane w DataGrid. Wszystko jest fajnie, gdy pracujemy na modelu danych, gdzie mamy pojedyncze pola, bez żadnych kolekcji. Mam taką klasę:

    public class Row
    {
        public DateTime Timestamp { get; set; }
        public IEnumerable<double> Samples { get; set; }
    }

Potrzebuję zbindować tak elementy kolekcji typu Row, aby pierwszą kolumną była właściwość Timestamp, a kolejne kolumny zależne od kolekcji Samples, również od jej wielkości. Ile elementów tyle kolumn.

Timestamp Variable 1 Variable 2 ...
26.03.2018 9:15:22 0.12412412 0.21512515 ...
26.03.2018 9:15:23 0.32523552 0.36324256 ....

Ten trzykropek symbolizuje ciąg dalszy kolumn i wartości. Domyślam sie, że trzeba zrobić jakis model, zawierający ObservableCollection i tą kolekcję podpinać. Ale nie wiem potem jak konkretnie podpinać, aby Timestamp i Samples stanowiły jeden wiersz.

Chciałbym, aby była możliwość późniejszego prostego bindowania jak przy zwykłych kolekcjach, czyli:

DataGrid.ItemSource = rows; // kolekcja typu IEnumerable<Row>

A DataGrid wie, że ma połączyć Timestamp z kolekcją Samples w postaci pojedynzego wiersza i z każdym kolejnym elementem. Domyślam się, że trzeba pobawić się w edycji szablonu DataGrid, ale jestem w tym zielony.

1 odpowiedź

0 głosów
odpowiedź 4 kwietnia 2018 przez Siemił Mądrala (7,380 p.)

Cześć.

Po pierwsze w xaml wyłączasz automatyczne generowanie kolumn:

<DataGrid x:Name="dataGrid" AutoGenerateColumns="False"/>

a w bekkodzie tworzysz, bindujesz i dodajesz kolumny do datagrida:

public MainWindow()
        {
            InitializeComponent();

            //Towrzenie przykładowej kolekcji
            List<Row> list = new List<Row>() {
                new Row() { Timestamp = DateTime.Now, Samples = new List<double>() {1,2} },
                new Row() { Timestamp = DateTime.MaxValue, Samples = new List<double>() {1.1,2.2,3.3,4.4}}
            };

            //Dodanie jej do datagrida
            dataGrid.ItemsSource = list;

            //Tworzenie kolumny dla właściwości Timestamp
            dataGrid.Columns.Add(new DataGridTextColumn()
            {
                Header = "Timestamp",
                Binding = new Binding("Timestamp")
            });
            
            //Określenie ilości dodatkowych kolumn
            int longestCollection = list.Max(i => i.Samples.Count());

            //Tworzenie dodatkowych kolumn oraz bindowanie ich do datagrida
            for(var i = 0; i < longestCollection; i++)
            {
                dataGrid.Columns.Add(new DataGridTextColumn()
                {
                    Header = $"Variable {i + 1}",
                    Binding = new Binding($"Samples[{i}]")
                });
            }
        }

Mam nadzieje że pomogłem.

Podobne pytania

0 głosów
0 odpowiedzi 272 wizyt
0 głosów
1 odpowiedź 1,087 wizyt
pytanie zadane 11 marca 2017 w C# przez PejtaM Użytkownik (550 p.)
+1 głos
1 odpowiedź 474 wizyt

93,657 zapytań

142,577 odpowiedzi

323,100 komentarzy

63,174 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...