Laden...

Binden an DataGrid- DataGrid

Erstellt von MMCSharp vor einem Jahr Letzter Beitrag vor einem Jahr 849 Views
M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr
Binden an DataGrid- DataGrid

Hallo zusammen,

Ich würde gerne an ein Datagrid in einem RowDetailsTemplate Binden. Leider komme ich nicht weiter, da ich es nicht schaffe das Grid im Grid anzusprechen im XAML. Wie kann ich das anstellen?

das hat für den übergeordneten DataGrid geklappt


 <TextBox Height="20" Width="200" Margin="3" Text="{Binding ElementName=Main_DataGrid,Path=SelectedItem.City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Nun Steckt aber eben in den RowDetails ein weiterer Grid den ich gerne auch binden würde. rein theoretisch so:


 <TextBox Height="20" Width="200" Margin="3" Text="{Binding ElementName=Main_DataGrid.SecondGrid ,Path=SelectedItem.CityHouses, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

was aber nicht funktioniert

2.078 Beiträge seit 2012
vor einem Jahr

Das geht nicht oder nur sehr, sehr umständlich.

Aber im zweiten Grid zeigst Du doch auch nur die Daten vom SelectedItem des ersten Grids an, warum bindest Du dann nicht gegen die entsprechende Property?


<TextBox Height="20" Width="200" Margin="3" Text="{Binding ElementName=Main_DataGrid, Path=SelectedItem.SelectedCityHouse, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Und das gleiche würde ich auch für's erste Grid machen.
Am DataGrid das SelectedItem ans ViewModel binden, dann kannst Du A. aus dem ViewModel heraus das SelectedItem steuern und B. an anderer Stelle einfacher daran binden.

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich wollte das VM nicht so überladen, deswegen wäre ich gern diesen Weg gegangen.

16.806 Beiträge seit 2008
vor einem Jahr

Das ist aber die Idee des Systems hinter MVVM in WPF.
Lohnt sich schon, das dann auch so zu machen, wie es konzipiert ist 😉

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich bringe das alles nicht auf die Kette..

Aktuell implementiert mein "Model", das die ObservabaleCollection lädt, nahezu die komplette logic für das Handling. Ich lade dort Daten aus der Datenbank (SQLServer), füge sie der Collection hinzu und registriere die Ereignise auf die Items. Adaptiv dazu werden in den registrierten Ereignishändlern dann die Daten in die Datenbank geschrieben bzw verändert. Das Ganze lade ich Async mit dem Befehl:


public async void DataLoading() { await Task.Run(() => Load_Warehouses()); }

private void Load_Warehouses()
        {
            var WMod = new WarehouseModel();
            WareHouseCollection = WMod.LoadWarehouses();
            RaisePropertyChanged(nameof(WareHouseCollection));
        }

Mache ich das so ansatzweise richtig....?

16.806 Beiträge seit 2008
vor einem Jahr

Collections (besonders ObservableCollection) sollte man in diesem Fall nicht neu zuweisen, sondern wenn dann Leeren und neu befüllen.
Ansonsten ist das eine neue Referenz und einige Bindungs / Event Themen referenzieren dann das falsche / ein anderes Objekte (aka Liste).

Auch das Modell erzeugst Du eigentlich nicht neu.

Eigentlich hast Du sowas, was auch das Tutorial zeigt:


public class MyViewModel
{
   public MyViewModel(IWareHouseRepository warehouseRepository) // Mit Dependecy vermeidet man, dass man die SQL Verbindung manuell erstellt und verwalten muss
   {
      _warehouseRepository = warehouseRepository;
   }

   public ObservableCollection<WareHouseModel> WareHouseCollection {get;}  = new();

   public async Task LoadWareHouses()
   { 
      WareHouseCollection.ClearItems();
      List<WareHouseEntity> wareHouses = await _warehouseRepository.GetAllAsync();
      foreach(var wh in wareHouses )
      {
         WareHouseCollection.Add(new WareHouseModel(wh.Id, wh.Name));
      }
   }

   public ICommand LoadWareHousesCommand
   {
       get { return new DelegateCommand(LoadWareHouses); } // bin mir nicht mehr sicher, aber glaub DelegateCommand war hier das richtige
    }
}

Im Editor runter getippt, sicher irgendwo nen Typo drin.

Daher: in deinem Ansatz sind schon paar Fehler 🙂

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Vielen Dank dafür!
Damit komme ich bestimmt weiter! Vielen Dank!

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Noch einmal vielen Dank! Deine Lösung hat mich weiter gebracht, da sie mich zu vielen interessanten Themen geführt hat und ich daran doch sehr viel gelernt habe! Ich habe nun das UnitOfWork- und Repository- Entwurfsmuster in Verbindung mit Dependency Injection Implementiert. Meine Lösung sieht wie folgt aus:


public ObservableCollection<LocationModel> WareHouseCollection { get; set; } = new();

        public async void LoadingWarehousesAsync()
        {
            isWarehousesLoading = true;

            if (WareHouseCollection.Count > 0)
                    WareHouseCollection.Clear();

            using (var UoW = new MSSQLS_UnitOfWork(new MSSQLS_EFContext()))
            {
                var Locations = await Task.Run(() => UoW.Addresses.GetAllAsync());

                foreach (var Location in Locations)
                {
                    WareHouseCollection.Add(
                       new LocationModel()
                       {
                           Id = Location.Id,
                           City = Location.City,
                           HouseNumber = Location.HouseNumber,
                           Postcode = Location.Postcode,
                           StockName = Location.StockName,
                           Street = Location.Street,
                       });
                }

            }
            
            isWarehousesLoading = false;
            
            RaisePropertyChanged(nameof(WareHouseCollection));
            RaisePropertyChanged(nameof(isWarehousesLoading));
        }

nur eine Frage hätt ich noch, da ich den Ladevorgang am Anfang ja brauche und er aber nicht im Konstruktor sein soll, wie starte ich ihn am besten? Meine Idee wäre ein Event in der View gewesen, auf das ich mich registriere, ViewLoading eventuell.