Laden...

DataGrid mit selbst gefüllter DataTable anzeigen

Erstellt von dr4g0n76 vor 2 Jahren Letzter Beitrag vor 2 Jahren 454 Views
dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 2 Jahren
DataGrid mit selbst gefüllter DataTable anzeigen

Ich möchte mit dem untenstehenden Code einen selbstgefüllten DataTable an die ItemsSource eines Datagrid übergeben.
Die Columns sind AutoGenerated.

Wenn ich den DataTable im Debugger Visualizer anschaue, dann ist auch alles so gefüllt, wie es sein soll.
Nur nachher auf dem GUI ist alles leer. Nur die Spalten und die Zeilen wurden richtig generiert, nur, wie eben halt schon gesagt, ohne Inhalt.
Was mache ich falsch?

Das XAML zum DataGrid sieht so aus:


<DataGrid x:Name="wiqlDataGrid" AutoGenerateColumns="True" ColumnHeaderHeight="25" Margin="125,99,10,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

EDIT: Ich hätte gerne das im DebuggerVisualizer angezeigte Bild live auf dem Screen in der App (siehe angehängtes Bild aus dem DebuggerVisualizer)


            try
            {
                Task<IList<WorkItem>> queryResult = queryExecutor.Query(query);
                IList<WorkItem> workItems = queryResult.Result;
                if (workItems.Count == 0 || workItems == null)
                {
                    Console.WriteLine("No workitems found.");
                    return;
                }

                DataSet dataSet = new DataSet();
                DataTable dataTable = new DataTable();
                dataSet.Tables.Add(dataTable);

                foreach (KeyValuePair<string,object> keyValuePair in workItems[0].Fields)
                {
                    dataTable.Columns.Add(keyValuePair.Key);
                }

                for (int j = 0; j < workItems.Count; j++)
                {
                    WorkItem workItem = workItems[j];
                    DataRow row = dataTable.NewRow();
                    int i = 0;
                    foreach (var item in workItem.Fields)
                    {
                        row[i++] = item.Value;
                    }
                    dataTable.Rows.Add(row);
                }
                DataView dataView = new DataView(dataTable);
                wiqlDataGrid.ItemsSource = dataView;
            }
            catch (AggregateException ex)
            {
                System.Windows.MessageBox.Show(ex.Demystify().ToString());
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Demystify().ToString());
            }


Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.079 Beiträge seit 2012
vor 2 Jahren

Warum weist Du die DataTable direkt zu? Dafür gibt's DataBinding und WPF ohne MVVM macht keinen Spaß.
Bei Tasks solltest Du NIEMALS (außer Du weißt, was Du tust und hast einen guten Grund) direkt mit dem Result arbeiten.
Console.WriteLine? In WPF-Anwendungen gibt es keine Konsole. Wenn's da einen Fehler gibt, fällt dir der also nicht auf.
Die DataTable habe ich noch nie mit dem DataGrid zusammen genutzt, ich würde aber die DefaultView benutzen - ob eine Eigene ein Problem ist, weiß ich aber nicht.

Und ich würde auch keine DataTable nutzen, die unterstützt (meines Wissens nach) keine Live-Aktualisierung beim Binding und angepasste Columns stelle ich mir auch schwierig vor.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 2 Jahren

Warum weist Du die DataTable direkt zu? Dafür gibt’s DataBinding und WPF ohne MVVM macht keinen Spass.
Bei Tasks solltest Du NIEMALS (ausser Du weisst, was Du tust und hast einen guten Grund) direkt mit dem Resultat arbeiten.
Console.WriteLine? In WPF-Anwendungen gibt es keine Konsole. Wenn’s da einen Fehler gibt, fällt Dir der also nicht auf.
Die DataTable habe ich noch nie mit dem DataGrid zusammen genutzt, ich würde aber die DefaultView benutzen – ob eine Eigene ein Problem ist, weiß ich aber nicht.
Und ich würde auch keine DataTable nutzen, die unterstützt (meines Wissens nach) keine Live-Aktualisierung beim Binding und angepasste Columns stelle ich mir auch schwierig vor.

Erstmal danke für Deine Antwort @Palladin007.

Klar, die Console ergibt keinen Sinn. Das liegt daran, dass ich viel experimentiert habe. Das war zuerst eine Konsolenanwendung mittags noch. 🙂
Dafür, um zuerst nur die Devops Items auszulesen.

Ich wollte eigentlich das Programm wegwerfen, wenn es funktioniert und einfach nur eine User Control daraus erstellen.

Und mir gings erst mal darum den Datatable anzuzeigen im Grid. Deswegen habe ich hier gar nichts bereinigt. Sondern nur probiert.
Ich habs auch schon mit Binding probiert gehabt. Das hatte halt auch nicht funktioniert.

Was ich teilweise auch noch ausprobiert hatte, war von hier:

https://www.dotnetspider.com/resources/34103-WPF-Binding-DataTable-WPF-Datagrid.aspx

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.079 Beiträge seit 2012
vor 2 Jahren

Ganz einfach 😉


<Window.DataContext>
    <local:MainViewModel />
</Window.DataContext>
    
<DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top" Content="Fill data" Command="{Binding FillDataCommand}" HorizontalAlignment="Left" />
    <DataGrid ItemsSource="{Binding Data.DefaultView}" AutoGenerateColumns="True" />
</DockPanel>


public class MainViewModel : INotifyPropertyChanged
{
    private DataTable? _data;

    public event PropertyChangedEventHandler? PropertyChanged;

    public DataTable? Data
    {
        get => _data;
        private set
        {
            _data = value;
            NotifyPropertyChanged();
        }
    }

    public ICommand FillDataCommand { get; }

    public MainViewModel()
    {
        FillDataCommand = new FillDataCommandImpl(this);
    }

    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private class FillDataCommandImpl : ICommand
    {
        private readonly MainViewModel _owner;

        public event EventHandler? CanExecuteChanged;

        public FillDataCommandImpl(MainViewModel owner)
        {
            _owner = owner;
        }

        public bool CanExecute(object? parameter)
            => _owner.Data is null;

        public void Execute(object? parameter)
        {
            _owner.Data = CreateDataTable();

            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }

        private static DataTable CreateDataTable()
        {
            var dataTable = new DataTable();

            for (int c = 0; c < 10; c++)
                dataTable.Columns.Add($"Column {c:00}");

            for (int r = 0; r < 1000; r++)
            {
                var row = dataTable.NewRow();

                for (int c = 0; c < 10; c++)
                    row[c] = $"Value {c:00}-{r:0000}";

                dataTable.Rows.Add(row);
            }

            return dataTable;
        }
    }
}

Aber das ist definitiv kein guter Code, nur das, was ich in 10 Minuten so hin gezimmert habe 😁

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 2 Jahren

Also das funktioniert soweit schonmal. Danke. 🙂
Das werde ich bei nächster Gelegenheit einbinden. Und das mit dem Binding wie das geht ist auch klar.
Den Code kann man ja nachträglich noch verbessern. Da das Ganze ein Testtool wird, ist hier ausnahmsweise erst mal Geschwindigkeit wichtiger.

EDIT:
P.S.: Testtool im Sinne zum Ausprobieren, nicht um es als Tester zu verwenden. 😉

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.079 Beiträge seit 2012
vor 2 Jahren

P.S.: Testtool im Sinne zum Ausprobieren, nicht um es als Tester zu verwenden. 😉

Nichts hält länger als ein Provisorium. 😉

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 2 Jahren

Nope. Hast zwar recht. Nur für mich wird es keins bleiben. Nur hier in der Firma halt.
Für meine eigenen Anwendungen, werde ich das auch benutzen. Da aber garantiert nicht als Provisorium. 😁 Da kann ich ja zum Glück selbst den Zeitaufwand und die Qualität bestimmen. 😁

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.079 Beiträge seit 2012
vor 2 Jahren

Werden solche Provisorien nicht gerade erst in Firmen zu wirklichen Problemen?
Und Du darfst sie dann nach ziehen, wenn man das tote Pferd nicht mehr weiter schieben will 😜
Aber müsst Ihr wissen ^^

Worauf ich mit dem Kommentar "kein guter Code" hinaus wollte:

Das lässt sich mit einem geeigneten MVVM-Framework deutlich vereinfachen, aber die Wahl eines Frameworks wollte ich nicht vorausgreifen, außerdem ist so besser ersichtlich, was überall passiert.
Außerdem habe ich den DataContext produktiv noch nie (naja, vor x Jahren vielleicht mal) im XAML erstellt, weil dahinter immer irgendwie DependencyInjection steht und ich das ServiceLocator-Pattern grausig finde.
Und dann noch ein paar projektabhängige Dinge, aber die sind halt projektabhängig und vermutlich gar nicht relevant ^^

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 2 Jahren

Das Problem ist zweigeteilt, sozusagen:

ich würde es gerne richtig machen. Deswegen werde ich es auch zu Hause für mich richtig benutzen. Da redet mir ja zum Glück keiner dazwischen.

Nur derjenige, der mir gerade vorgibt, was ich machen soll, der will das nicht.
Also soll er sich selbst darum kümmern. Ich mach nur den Proof of Concept.
Wenn es dann aber nachher nicht richtig funktioniert, dann ist er selbst schuld. Dann kümmere ich mich nicht mehr darum.

Das ist der Hintergrund.

Denn: ich sehe das genauso wie Du. Sonst hat man wieder Ärger hinterher. Whatever. Selbst schuld, wenn er das so will.

Es gibt nichts daran auszusetzen, an dem was Du nennst.
Im Gegenteil. Meinst Du ein eigenes MVVM Framework oder ein vorhandenes? Muss zugeben, so richtig tief in WPF bin ich nicht drin.
Natürlich nicht unwissend, aber längst noch nicht so, wie mit Windows Forms damals.

P.S.: Ich gebe Dir mal noch 2/3 Beispiele, warum das gerade in der Firma so läuft, damit Du den Hintergrund mehr verstehst,
Ich bin momentan dran eine Automatisierung zu erstellen auf Azure DevOps. Eigentlich.
Nur.. hier in dieser Firma sind so viele dringend, dass man dann dauernd eine neue Prio 1 bekommt. Soweit so gut.

Z.B. war eins der ersten Dinge, dass ich aufgedeckt habe:

1.) Die Firma benutzt SQL Express 2014. Weil das ja kostenlos geht. Laut denen. Hab das bisher noch nicht genauer überprüft.
Nur... was ich dann festgestellt hatte, dass die Datenbank beim Kunden zu 98% voll ist und jeden Moment überlaufen kann.

Hab darauf mehrmals hingewiesen. Nur, dieser Typ will das nicht. Er meinte, wir können uns noch 2 bis 3 Monate Zeit lassen.
LOL. Wenn die Datenbank Files aber alle 3 Tage bis zu 100 MB zunehmen…

SQL Express hat ja das 10 GB Limit.

Also bin ich irgendwann höher zu seinem Vorgesetzten (von – nennen wir ihn mal A). Weil er mich immer dementiert hat.
Sein Vorgesetzter C meinte sofort: klar. Datenbank retten ist wichtiger als alles andere. Wir können uns so was nicht leisten.
Gut. Und dieser vorgesetzte C meinte, ist gut. Brich alles ab. Mach eine Lösung dafür zumindest als Workaround.

2.) Mit den Übersetzungen für neue Sprachen ebenfalls der gleiche Mist.

3.) Und jetzt weisst auch, denke ich, warum ich da nur ein Provisorium mache. Das ist und bleibt dann seine Verantwortung.

Vor allem, wenn das noch lange so weitergeht, dann und meine Bugs weiter gelöscht werden oder als zu unwichtig deklariert werden
und deswegen gelöscht und der Kunde und sich sein Vorgesetzter fragt, warum die Probleme nach 2 Monaten immer noch nicht gelöst sind…
Dann habe ich da eh nicht mehr lange was verloren.

So, das musste ich mal loswerden.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.079 Beiträge seit 2012
vor 2 Jahren

Meinst Du ein eigenes MVVM Framework oder ein vorhandenes?

Entweder oder - es gibt ja ein paar vorhandene Frameworks, die auch viel genutzt werden. Ich arbeite aktuell mit dem Windows Community MVVM Toolkit
Allerdings habe ich persönlich noch keine Implementierung gesehen, mit der ich zufrieden gewesen wäre.
Hier würde ich also darüber nachdenken, eine eigene Implementierung zu entwickeln, allerdings fordert das auch einiges an Erfahrung im Umgang mit MVVM. Außerdem verliert man dann den großen Vorteil, dass ein bestehendes Framework von vielen Entwicklern genutzt und getestet wurde und eine Community samt Doku hat.

Für die meisten Projekte tut's vermutlich ein bestehendes Framework, alles darüber hinaus sind Nischen-Anforderungen und lassen sich meist aus einer anderen Richtung auch ganz gut umsetzen.

Und jetzt weisst auch, denke ich, warum ich da nur ein Provisorium mache.

Ich hab auch mal in so einer Firma gearbeitet. Jetzt arbeite ich da nicht mehr ^^
War damals beruflicher Tiefpunkt und das Leben ist jetzt so viel entspannter.
Oder man legt sich eine "Nach mir die Sintflut"-Einstellung zu, wie einige Kollegen in der Firma, dann kann man auch gut leben, bleibt aber technologisch garantiert auf der Strecke.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.