Wyświetlanie danych z dynamicznego zapytania sql w DataGrid

0

Witam,
Próbuję zrobić aplikację, w której od czasu do czasu będzie importowana nowa tabela z pliku do wyświetlenia - import z xls do SQL Server.
Chciałbym mieć funkcjonalność, w której te dane będą zawsze wyświetlane w tym samym DataGrid lub ewentualnie w nowej karcie w innym DataGrid. Ale chciałbym uniknąć zmian w kodzie. Chciałbym wczytać odpowiednie zapytanie, np. z zewnętrznego pliku (np. xml, txt).
Czy mógłbym prosić o doradzenie w jakim kierunku powinienem pójść. Czy takie coś da się np. zaimplementować we wzorcu MVVM?

0

Ale chciałbym uniknąć zmian w kodzie

Bez zmian w kodzie się nie da.

Chciałbym wczytać odpowiednie zapytanie, np. z zewnętrznego pliku (np. xml, txt)

Jakie zapytanie? w jakim celu?

import z xls do SQL Server

Co właściwie ma robić aplikacja?

0

@Grzegorz Świdwa:
Aplikacja ma wyświetlać po prostu wyświetlać w przystępny sposób dokumenty, zaimportowane do różnych tabel ( w większości będą to pliki xls, ale może się zdarzyć też inny format).
Takie zaimportowane dane wiąże ze sobą po kolumnach (np. miasto, nazwisko).
Czyli jest np. 1 tabela wzorcowa, gdzie wyświetlam jakieś dane - na podstawie zapytania, które w każdej chwili mogę zmienić - może się zmienić ilość kolumn do wyświetlenia lub w ogóle tabela.
Załóżmy, że jest to

SELECT * FROM TABLE1

Jak kliknę w rekordzie w DataGrid np. kolumnę Nazwisko mają mi się też wyświetlić nazwy dokumentów w których jest też to nazwisko - czyli po prostu inne tabele, które aktualnie mam w bazie.
Czyli, ma się w skrócie wykonać zapytanie:

SELECT * FROM TABLE2 WHERE NAZWISKO LIKE '%TutajParametrPrzekazanyZTabeli1%'

Po kliknięciu na którąś z pozycji otworzy mi się konkretny dokument w tym samym DataGrid co wcześniejszy dokument.
Zrobiłem kiedyś coś podobnego, ale wszystko mocno nieprzejrzyście. Najchętniej bym zrobić to we wzorcu MVVM, ale nie wiem jak do tego podejść - w przypadku kiedy struktura tabeli może być dynamiczna.

2

najprościej jest to zrobić przekazując do DataGrid swój własny model z zaimplementowanym interfejsem INotifyPropertyChanged:

public class ItemViewModel : INotifyPropertyChanged
{
     public int Id { get ; set ; }
     public string Name { get; set; }
     public string Description { get; set; }
}

W modelu widoku:

public IList<ItemViewModel> Items = new ObservableCollection<Items>();

W widoku:

<DataGrid ItemsSource="{binding path="Items"}">

Wyświetlanie tych danych należy do wyobraźni twórcy. Kliknięcie w item powoduje wywołanie zdarzenia np. ItemClicked w którym zmieniasz widok / wyświetlasz tooltip / cokolwiek.
A jeżeli chodzi o wyświetlanie różnych tabel zrób sobie IValueConverter.

public IList<ItemViewModel> Items = new ObservableCollection<Items>();

private IList<ItemViewModel> selectedItems;
public IList<ItemViewModel> SelectedItems{
     get{ return selectedItems; }
     set{
          selectedItems = value;
          OnPropertyChanged("SelectedItems");
     }
}

IValueConverter będzie zbindowany do właściwości SelectedItems i będzie sterować property Visibility Twoich DataGrid

screenshot-20201129130824.png

Nie wiem czy o to Ci chodziło :<

0

@Grzegorz Świdwa: Chyba o coś podobnego, tylko właśnie u Ciebie jest klasa ItemViewModel ma z tego widzę znane zmienne (Name, Description, itd.). W moim przypadku ja nie wiem jakie będą zmienne (pola) - bo rozumiem że są one odwzorowaniem kolumn tabeli. Chyba że coś źle rozumiem. Po prostu nie wiem jak mam zaprojektować Model czy ViewModel pod kątem różnych typów.
Nie wiem czy tu ktoś nie miał podobnego problemu, ale nie korzystałem nigdy z typów anonimowych, tym bardziej przy MVVM:
https://stackoverflow.com/questions/20405058/collection-of-anonymous-types-using-a-datagrid-with-converter

1

To proste. Robisz metodę do pobierania danych, gdzie Key to nazwa kolumny a Value to jej wartość:

public  List<KeyValuePair[]> GetData()
{

}

Następnie robisz metodę wybierającą listę nazw kolumn:

public  string[] GetColumnNames(KeyValuePair[] OneRowData)
{
     return OneRowData.Select(x => x.Key).ToArray();
}

Następnie zgodnie z tym linkiem tworzysz taką tabelę jaką zechcesz i wyświetlasz dane
https://stackoverflow.com/questions/15655271/dynamically-add-columns-to-datagrid-in-wpf

public void buildTable(string[] headers)
{
    myGrid.Columns.Clear();
    foreach (string header in headers)
    {
        DataGridTextColumn c = new DataGridTextColumn();
        c.Header = header;
        myGrid.Columns.Add(c);
    }
}

Dodatkowo:
https://stackoverflow.com/questions/18452134/filling-a-datagrid-with-dynamic-columns - bindowanie do Dictionary<string, object>, na pewno Ci się przyda
https://stackoverflow.com/questions/704724/programmatically-add-column-rows-to-wpf-datagrid - Gdybyś miał kilka ViewModel możesz je sobie zmieniać i tworzyć binding w modelu

0

@Grzegorz Świdwa: Dzięki bardzo. Spróbuję

1 użytkowników online, w tym zalogowanych: 0, gości: 1