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?
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?
@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.
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
Nie wiem czy o to Ci chodziło :<
@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
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
@Grzegorz Świdwa: Dzięki bardzo. Spróbuję