Laden...

Multiple Views in einer anderen View (TabControl)

Erstellt von CoPyMaus vor 2 Jahren Letzter Beitrag vor 2 Jahren 649 Views
C
CoPyMaus Themenstarter:in
12 Beiträge seit 2021
vor 2 Jahren
Multiple Views in einer anderen View (TabControl)

Ein bischen viel Text. Aber ich hoffe dennoch, das man sich die Mühe macht, diesen Beitrag gründlich durch zu lesen und nicht nur überfliegt. (8956 Zeichen)

Hallo liebe Community,

das es mein erster Beitrag hier ist, will ich zunächst einmal etwas über mich bekannt geben.
Zunächst, ich bin bereits 48 Jahre und habe im Alter von 13 angefangen, das eine oder andere Geschnipsel herunter zu schreiben. Meine Zeit reicht zurück bis zum Commodore 64. Naja, das war wirklich nur Spielerei. Aber damit hat alles angefangen. Anstatt nur mit dem Computer zu spielen, interessierte es mich, wie so ein Ablauf von Programm eigentlich von statten geht. Die damaligen PEAK und POKE Befehle im Commodore Basic, habe ich im Laufe der Zeit zwar vergessen, aber dennoch hat es mir geholfen, mein Weg zu finden, so das ich seit dem selber in der Entwicklung kleiner Anwendungen befindlich bin. Mit der Geburt des Internet, hat sich jedoch mein Interessengebiet etwas verändert. Die ersten Seiten (Boah, waren die Grottenschlecht und sorgten für Augenkrebs) konnte ich recht schnell zusammen schustern. Naja, HTML ist ja nicht sonderlich schwer. Mit PHP und MySQL ging meine Entwicklung weiter. Später interessierte mich dann auch JavaScript, da durch Prototype und Ajax neue Möglichkeiten geschaffen wurden.

Jetzt heißt es wahrscheinlich wieder: "Ohje, schon wieder ein Scripter". Ja, ich gebe zu, das ich ein Scripter bin. Aber ohne diese Scripter, gäbe es diese Seite schließlich auch nicht.

Seit gut 6 Monaten jedoch, beschäftige ich mich mit C#. Ich entdeckte die Möglichkeiten, all das, was ich vorher bereits gemacht habe, mit einer App in C# verbinden zu können. Möglichkeiten, die für den einen oder anderen "User", Dinge zu vereinfachen. Alles in einem, ich bin begeistert. (Ok, etwas spät, das ich mir C# ansehe, aber: Selbst im meinem Alter, ist es nicht mehr so leicht, sich neues anzueignen. Aber ich versuche es.

Ich habe in den 6 Monaten, dank vieler User/Programmierer auf der großen weiten Welt, viel in Erfahrung bringen können. Die eine oder andere kleine App habe ich auch schon zustande bekommen. Ich gehe nach dem "Do-It-Yourself" System. Das bedeutet, was ich lese, probiere ich auch aus, um es selber zu sehen und mir einzuprägen. (Sofern es mich interessiert).
Ich bemühe ständig das WWW und kenne auch Suchfunktionen, die mir das eine oder andere zeigen, was ich benötige.

Aber dieses mal, habe ich ein Anliegen, wo ich einfach patu nicht weiter komme. Dazu gleich mehr.

Eines möchte ich dennoch los werden. Es sind nicht viele, die so etwas schreiben, aber ich finde, das die gebührende Anerkennung ein wesentlicher Bestandteil einer guten Community ist und ich mich daher, bei allen Bedanken möchte, die anderen weiter geholfen haben und jene, die auch weiterhin helfen werden. Dieses Danke geht an alle Portale, Blogs und was es noch so gibt, im weitem Internet. Ohne euch, stände mein C# nicht da, wo ich jetzt bin.

So, nun zu meinem Anliegen:
Wie bereits vorher erwähnt, beschäftige ich mich seit gut einem halben Jahr mit C#. Vieles habe ich gelernt, vieles haue ich auch durcheinander, weil es teilweise echt "to much" wird und ich dafür noch das Verständniss entwickeln muss. Die ersten Apps, waren doch recht linear geschrieben. Es waren kleine Apps. Daher nicht weiter Interessant.
Nun habe ich ein etwas größeres Projekt und ich merkte schnell, das es eine besondere Aufmerksam erfordert, damit man sich im eigenem Code noch auskennt. Dann, durch einen Zufall stieß ich auf das MVVM. Nachdem ich jetzt bereits mehrere Tage damit verbracht habe, die Vorgehensweise und den Aufbau einer MVVM verständlich und umsetzbar zu machen (natürlich nach benannten "Do-It-Yourself" Verfahren), kann ich mittlerweile behaupten, das ich es geschafft habe, ein eigenes Konzept mit MVVM umzusetzen. Die Trennung von MainView und ViewModel ist genau das, was die Übersichtlichkeit seines eigenen Codes, um ein vielfaches vereinfacht. Auch die Möglichkeit, später nur die View neu zu gestalten, um die App / das Programm auf andere Betriebssysteme portieren zu können, ist eine (finde ich) geniale Lösung, um nicht alles noch einmal schreiben zu müssen. (Im Augenmerk habe ich da derzeit Xamarin, aber erst später)

Doch gibt es etwas, was ich nicht verstehe, bzw. Sehe ich den Wald vor lauter Bäumen nicht!

Es geht um Multiple Views in einer View.
Ich schreibe derzeit eine App, die für meine RadioCommunity ist. Dabei geht es um ein automatisiertes ServerProgramm, das als Service/Programm mit dem Server gestartet werden soll.
Dabei soll das Programm natürlich alle relevanten Aktionen ausführen, die nach einem "ich sage mal" Stromausfall benötigt werden, um das Radio wieder in Gang zu bekommen. Demnach gibt es viele Einstellungsmöglichkeiten. Im Weiteren soll dieses ServerProgramm auch selber als Server fungieren. Eine zweite App, verbindet sich mit der ServerSoftware und bietet Nutzern jene Möglichkeiten, die im zur Verfügung gestellt werden.

Ich schreibe wieder zuviel. wahrscheinlich interessiert es nicht wirklich, was mein Vorhaben ist.

Multiple View in einer anderen View:
Mein Vorhaben basiert auf die Trennung der einzelnen Tabs in einem TabControl. Dabei soll jeder Tab seine eigene View erhalten (und jede View hat sein eigenes ViewModel). Dabei ist es mir egal, ob die Tabs bereits in der xaml angelegt sind, oder die Tabs dynamisch erzeugt werden. Ich habe sehr viel bereits im Netz darüber gelesen. Ja, die Beispiele funktionieren. Aber immer nur mit einer View. Sobald ich versuche eine zweite View hineinzubringen, werden entweder die ViewModels nicht erkannt, gestartet oder ich lande in irgendwelcher Exceptions, die ich nicht mehr zuordnen kann, weil diese im MainWindow (erste Zeile) rausgeworfen werden. Auch habe ich es schon geschafft, VS zum Absturz zu bringen, weil der Debugger sein zeitliches segnen wollte.

Also, was ich erreichen möchte:

MainWindow
eigene Instanz, soll nur wesentliche Steuerelemente wie Schließen, Minimieren, Maximieren und Wiederherstellen enthalten. <- Das habe ich bereits geschafft. Da ich mit WindowStyle="None" arbeite, musste ich die Steuerelemente entsprechend wieder herstellen. (Aus Designgründen)

Das MainWindow hat also schon mal sein eigenes ViewModel mit einer View, wo fast nichts drin ist. Lediglich die Grundfunktionen eines Window.
Darin möchte ich das MainContent mit samt ViewModel integrieren. Der MainContent enthält lediglich das Grundgerüst für View. Darin ist eigentlich nur ein TabControl enthalten.

Wie bereits erwähnt, bis hierhin habe ich es schon durch Anleitungen hin bekommen. Aber jetzt:

Ich möchte fünf bis sechs Tabs anlegen. Wie gesagt, mir ist es zunächst egal, ob ich die in der Xaml anlege, oder ob diese dynamisch erzeugt werden. Wobei letzteres wäre das Non-Plus-Ultra. Ein CodeBeispiel hat mir gezeigt, wie ich Tabs dynamisch anlege. Jedoch schaffe ich es einfach nicht, ein Binding zu einer View bzw. ViewModel mit zu übergeben.

In diesen Tabs soll jeweils eine eigene View (mit Binding auf das ViewModel) angezeigt werden. (Tab1 => View1, Tab2 => View2, Tab3 => View3..... usw)
Mein Gedanke geht sogar soweit, diese "SubViews" noch mal zu trennen und jeweils nur die einzelnen Elemente in einem Sichtbaren Bereich einzubinden (SubSubView). <- Und da hapert es bei mir. Ich bekomme es einfach nicht hin. Ich habe bereits soviel dazu gelesen, das ich selber nicht mehr weiß, was da richtig und falsch ist. Jeder macht es anders. Aber die Beispiele zeigen meist nur "eine" View in einer anderen.

Also noch mal Zusammengefasst:

MainWindow <-> MainContent (beinhaltet TabControl) <-> SubView auf jeden einzelnen Tab | (<-> SubSubView für die einzelnen Elemente bzw. Bereiche)

Da ich davon überzeugt bin, das gerade hier, viele erfahrene Entwickler zugegen sind (Habe schon einige interessante Artikel gelesen), dachte ich mir, das ich jetzt einfach mal Frage. Vielleicht hat der eine odere Andere einen Ansatz. Zu einem Projektbeispiel, das ich analysieren, auswerten und testen kann, um die Funktion zu verstehen, habe ich natürlich keine Einwände.

Ach noch was, bevor ich es vergesse, hier noch folgende Eckdaten / Informationen:

  • GUI = Visual Studio 2019 (up to date)
  • .Net Framework 4.8
  • WPF
  • ich möchte verhindern, zusätzliche Librarys zu verwenden. Im Netz kursieren viele Beispiele, die auf MVVMLight verweisen. (Oder war es MVMLight?) Es ist zwar nett, das mit solchen Librarys Dinge vereinfacht werden, aber ich möchte es doch gleich richtig machen. (Hört sich dumm an, aber so bin ich eben) Zumal ich rechne mit der Dummheit diverser Nutzer, die einfach Dateien löschen, im Glauben, das sie es eh nicht brauchen. (Ok, ist jedem selber überlassen, eine Software 100 mal und mehr zu installieren, wenn es nicht mehr funktioniert. Aber wenn man es vermeiden kann?)

So, genug geschwätzt. Ich bedanke mich schon mal bei jedem, der sich die Mühe macht, mir helfen zu wollen.
"Hochachtungsvoll"
CoPyMaus

P.S. Gerne nehme ich auch Angebote für privates BrainStorming entgegen. Jeder Teacher, der mir was begreiflich machen kann, ist mir willkommen. Einfach PN schreiben.

16.807 Beiträge seit 2008
vor 2 Jahren

Zum Problem:
Das Erzeugen von Tabs im Code Behind ist eigentlich kein Non-Plus-Ultra, sondern verletzt eigentlich die Binding-Idee von WPF und MVVM.
Bedeutet: Du solltest primär den Binding Weg gehen und Code-Behind wenn möglich ganz weg lassen.

Bei Tabs hat i.d.R. jeder Tab sein eigenes ViewModel und entsprechende Inhalte.
Das Window selbst ist ebenfalls ein ViewModel, wie auch das Tab Control. Ergo: ein ViewModel kennt seine Child-ViewModels.

Hinweise zu Deinem Text:

GUI = Visual Studio 2019 (up to date)

Visual Studio ist nicht die GUI, sondern Deine IDE.
GUI ist in diesem Fall WPF.

ich möchte verhindern, zusätzliche Librarys zu verwenden .. [....]aber ich möchte es doch gleich richtig machen

Da hilft es Dir nicht, dass "Du halt so bist". Damit machst Du Dir selbst das Leben schwer und kannst gewisse Dinge ganz einfach nicht alleine stemmen, weil das gesamte moderne Ökosystem von Software - Java, NodeJS, .NET - darauf aufgebaut ist, dass externe Bibliotheken (meist Open Source) verwendet werden.
Die jeweiligen Frameworks bieten i.d.R. "nur Grundfunktionen". Pauschal daher externe Libs auszuschließen, ist eher unschlau; um es nett auszudrücken.
Im Zweifel kann man dann nur sagen: selbst schuld, pech gehabt.

Gerade im Bereich von WPF haben sich MVVM Frameworks oder Dinge wie Reactive Extensions oder MahApps etabliert.
Reactive Extensions zB. ist eines der größten Open Source Projekte und im Zusammenhang mit .NET sogar mittlerweile Teil der .NET Foundation.
Und diese Frameworks haben auch nichts mit "richtig" oder "falsch" machen zutun.

Falls Du Code-Vorlagen willst, so durchforste GitHub, ob Du was findest.

PS: ja Dein Text ist sehr lang, mit viel verwirrenden Stellen, die für das Problem keine Rolle spielen 😉
Und Du hast evtl. die ein oder andere Ansicht, die Dir beim Schreiben von guter Software wahrscheinlich im Weg steht - gerade das Thema Dependencies.

C
CoPyMaus Themenstarter:in
12 Beiträge seit 2021
vor 2 Jahren

Ok, ich habe mir echt Mühe für mein ersten Thread hier gegeben. Aber ich bin eben auch nicht perfekt und entschuldige mich dafür, wenn das eine oder andere, Verwirrend erscheint.

Visual Studio ist nicht die GUI, sondern Deine IDE.
GUI ist in diesem Fall WPF.

Danke für den Hinweis. Eigentlich hätte ich es wissen müssen. Aber, ich haue "noch" einige Begriffe durcheinander. Durch C# habe ich erst mal Begriffe kennen gelernt, die es in der (Scripter- Welt [PHP]) nicht gibt. Ich kenne " public function blablahblah(bla) " oder einfach nur " function blahblah(blah) ", wo es egal ist, ob ich ein int, string oder object übergebe. PHP nimmt eben alles so wie es kommt, es sei denn, das man explizit eine Bestimmung der Variable vornimmt. Und da ist es wieder, das Wort Variable. In ganz C# habe ich diesen Begriff bisher nicht gesehen. Hier wird doch eher von Fields, Members, Properties und Methoden gesprochen. Was jetzt genau was ist, steige ich so allmählich durch.

Es ist für einen alten Scripter eben nicht einfach, sich einer neuen Sprache zu bemächtigen. Genauso, wenn man versucht, Chinesisch zu lernen. Aber wer nicht wagt, der auch nicht gewinnen kann.

Zu deinem eigentlichen Beitrag:
Ich habe "ehrlich" schon einiges im Web durchgekämmt. Darunter auch GitHub. Nur leider noch nichts gefunden, was mein Verständniss in dieser Thematik weiter bringt. Sicherlich werde ich weiterhin suchen und vielleicht finde ich die Lösung. Vielleicht bekomme ich aber auch den "AHA- Effekt" und mir fällt es wie Schuppen von den Augen. Alles ist möglich.

Ich möchte fünf bis sechs Tabs anlegen. Wie gesagt, mir ist es zunächst egal, ob ich die in der Xaml anlege, oder ob diese dynamisch erzeugt werden. Wobei letzteres wäre das Non-Plus-Ultra.

Hier war nicht vom Code-Behind die Rede sondern letzendlich eine Methode innderhalb der MainView bzw. einer weiteren Klasse. Sorry, für das Verständnissproblem.

Im Code-Behind habe ich derzeit lediglich zwei Methoden, weil ich dafür noch keine Alternativen gefunden habe.


        private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e) // Window wieder bewegbar machen
        {
            if(e.ChangedButton == MouseButton.Left)
            {
                Application.Current.MainWindow.DragMove();
            }
        }
        bool _shown;
        protected override void OnContentRendered(EventArgs e) // Warten bis das Window vollständig aufgebaut ist. Danach weitere Hintergrundaktionen starten.
        {
            base.OnContentRendered(e);

            if(_shown)
                return;

            _shown = true;
        }

Ich mag es, wenn ich ein Programm starte, das ich sehen kann, was es gerade macht.

Gut meine Denkensweis mag vielleicht nicht ganz konform sein. Vielleicht ist des Rätsels Lösung tatsächlich in einer der Libs versteckt. Wenn es einfach nicht anders geht, werde ich auch darauf zurück greifen. Ja, ich mach mir das Leben schwerer, als es sein kann. Aber dafür weiß ich auch, was ich bisher in meinem Leben gemeistert habe, ohne (Querdenken an) eine Firma damit beauftragen zu müssen. (Querdenken aus [Firma = Libs])

Ich bin keiner, der erst um Hilfe schreit und dann den präsentierten Code, sein eigen nennt. Sicherlich schaue ich mir gerne etwas ab, probiere es aus und wenn es funktioniert: Voila - ein Schritt weiter, wieder mal Happy. Aber ich vergesse niemals, das ich mir mögliche Anregungen aus dem Netz "erschlichen" habe und werde diese Schnipsel auch niemals mein eigen nennen. Das was ich mir selber erarbeitet habe, ist meins. Das was ich bekommen habe, bleibt seins.

Gut, ich schreibe viel und für die meisten wohl eher zu viel. Ich bin eben der Meinung, je ausführlicher, umso besser kann geholfen werden. Leider lese ich oft genug Beiträge, wo sogar ich mich Frage: "Hää. was will der jetzt eigentlich". Will mich nicht ausschließen. Ist mir bestimmt auch schon passiert.

Lieben Gruß
CoPyMaus

16.807 Beiträge seit 2008
vor 2 Jahren

In ganz C# habe ich diesen Begriff bisher nicht gesehen. Hier wird doch eher von Fields, Members, Properties und Methoden gesprochen. Was jetzt genau was ist, steige ich so allmählich durch.

Dann scheinst bislang nicht ein mal in die Doku geschaut zu haben.
https://docs.microsoft.com/de-de/dotnet/csharp/tour-of-csharp/types bzw genauer Typen – C#-Programmierhandbuch
Wie Du siehst, gibt es in C# sehr wohl Variablen, sind dokumentiert und was anderes als Fields, Properties und Methoden.
Member wiederum ist nur ein Oberbegriff, siehe Member – C#-Programmierhandbuch

Ansonsten sind die Bezeichner von C# und Php relativ ähnlich, zumindest die der Grundkonstrukte

  • Variablen => Variablen
  • Eigenschaften => Eigenschaften und Felder (je nach Art)
  • Methoden => Methoden

Im Code-Behind habe ich derzeit lediglich zwei Methoden, weil ich dafür noch keine Alternativen gefunden habe.

Bin kein WPF Profi aber würde sagen, dass man das so nicht macht.
Vielleicht kann da ein WPF-Profi einen besseren Vorschlag machen.

Zumindest bei OnContentRendered bin ich mir relativ sicher, dass man sowas über einen Command löst.
[Artikel] MVVM und DataBinding

Aber dafür weiß ich auch, was ich bisher in meinem Leben gemeistert habe

Werde die Aussage nicht bewerten, aber musst selbst wissen, wie viel Dir Deine Zeit Wert ist.
Hinter Fameworks wie MahApps stecken dutzende von Entwicklerjahre - von Profis.

Du kannst die nächsten Moante versuchen Deine Lösung zu finden, oder Du verwirfst das Not-invented-here-Syndrom und freust Dich, dass sich andere um eine Lösung gekümmert haben, die Du für Deine Zwecke adaptieren kannst.

PS: ja, verstehe Deinen Grund der langen Texte.
In Foren schreckt das jedoch die meisten Helfer ab.

C
CoPyMaus Themenstarter:in
12 Beiträge seit 2021
vor 2 Jahren

Vielen Dank für deinen Beitrag.

Ich habe mal eben in die Links reingeschaut. Ich werde sie mir noch einmal genauer ansehen. Aber ich denke, das es mich zumindest in Sachen "Begriffe in C#" noch mal weiter bringen wird. Ich habe tatsächlich den Begriff Variable entdeckt und festgestellt, das es genau das gleiche ist, was ich aus PHP her kenne. Nur das diese in C# explizit mit Typen oder Objekte definiert / referenziert werden müssen. (War das jetzt so richtig?)

Not-invented-here-Syndrom

Lach, den Begriff kannte ich bis heute nicht. Ok, ich bekenne mich Schuldig. Aber es ist niemals zu spät, etwas zu ändern. (Wenn ich die Einsicht gewinne)

CoPyMaus

2.078 Beiträge seit 2012
vor 2 Jahren

Vorweg:

ja, verstehe Deinen Grund der langen Texte.
In Foren schreckt das jedoch die meisten Helfer ab.

Ich bin bei dem Thema ganz sicher nicht fehlerfrei, aber diesmal aus der anderen Sichtweise: Mich hat's abgeschreckt 😁
Ganz besonders, dass ich erst nach ein paar Absätzen das "So, nun zu meinem Anliegen" und wieder ein paar Absätze später das "Also, was ich erreichen möchte" gefunden habe ...
Ich beziehe mich daher nur auf das, was ich danach gelesen habe, sorry 😁

TabControl:
Das TabControl kann sowohl dynamisch als auch statisch.
Für dynamisch sind die Properties ItemsControl, ItemTemplate und ContentTemplate.
Für statisch kanst Du einfach TabItems in XAML definieren.
Grob im Browser getippt:


public class MyTabViewModel
{
    public ObservableCollection<MyTabItemViewModel> MyTabs { get; }
}


<TabControl ItemsControl="{Binding MyTabs}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TitleText}" />
        <DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ContentText}" />
        <DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

Damit könntest Du zur Laufzeit Tabs hinzufügen und entfernen, WPF reagiert dann live.
Wenn das nicht notwendig ist, reicht aber auch der einfachere Weg:


public class MyTabViewModel
{
    public MyTabItem1ViewModel MyTab1 { get; }
    public MyTabItem2ViewModel MyTab2 { get; }
}


<TabControl>
    <TabItem Header="{Binding MyTab1.Title}">
        <TextBlock Text="{Binding MyTab1.Content}" />
    </TabItem>
    <TabItem Header="{Binding MyTab2.Title}">
        <TextBlock Text="{Binding MyTab2.Content}" />
    </TabItem>
</TabControl>

OnContentRendered & StackPanel_MouseDown:
Für Beides gibt es meines Wissens nach keine direkte Lösung mittels Commands, das Prinzip funktioniert aber trotzdem, man sich bloß etwas dazu bauen.
Wie man das macht, dafür gibt's viele Wege, z.B.: AttachedProperties, Trigger (Interactivity) oder Behaviors (auch Interactivity).
Oder Du nutzt weiter CodeBehind, das ist mit MVVM nicht verboten, nur solltest Du darauf achten, dass Du die Logik, die da nichts verloren hast, konsequent verbannst.
Besser wäre natürlich, Du verzichtest ganz auf CodeBehind, in den allermeisten Fällen geht das und Du kommst nicht auf die idee, irgendwelche Logik hineinzuschreiben.

Das ist jetzt vielleicht etwas viel, ich hab es bewusst nicht ausführlicher erklärt, um nicht gegen meine eigene Kritik zu verstoßen, außerdem gibt's massig Anleitungen online.
Lies aber lieber ein/zwei Artikel mehr und überlege, ob das Beschriebene wirklich zu MVVM passt, denn leider sind so einige Posts/Tutorials nicht gut geschrieben...

Bei beiden Methoden frage ich mich aber auch: wozu?
Das Bewegen eines Fensters verbieten ... ich hasse es! Und wahrscheinlich lässt sich das gleiche Ziel auch viel besser erreichen.
Genauso, dass Du Dinge erst nach dem Rendern machen willst, mit einer sauber gebundenen View ist das oft gar nicht nötig, weil WPF alles automatisch macht.
Für Letzteres hatte ich bisher nur einen einzigen Fall, wo ich keine bessere Lösung gefunden habe und ich weiß nicht mehr, ob da nicht doch nur der Zeitdruck das Problem war.

Not-invented-here-Syndrom:
Von mir ein kleiner Erfahrungsbericht, was passiert, wenn man möglichst auf externe Libraries verzichtet:
Ich "darf" seit ca. einem Jahr bewundern, was passiert, wenn vom Chef verboten wird, externe Libraries zu verwenden, stattdessen soll man die ebenfalls vom Chef (weiter-) entwickelten Alternativen benutzen. Das betrifft sehr vieles, von Logging über Serialisierung bis zur HTTP-Requests. Manches ist ein Wrapper, manches komplett selbst entwickelt.
Meine Erfahrung damit: Es ist die Hölle.
Selbst einfachste Dinge wie ein simples Logging werden zu einer Herausforderung, weil diese selbst gebastelten Dinge meist nicht zuende gedacht wurden, wir deshalb für neue Projekte daran etwas ändern müssen, oft aber nicht können/dürfen, weil das alte Projekte gefährdet.
Das Ergebnis ist, dass mit jedem Projekt weitere Dinge an die vorhandenen selbst gebauten Frameworks "angeklebt" werden, um ja nichts kaputt zu machen und nach ein paar Jahren hast Du einen Knäuel aus Klebestreifen und ... "Zeug", den niemand mehr wirklich beherrscht. Die Projekte dauern immer länger, die Kollegen sind genervt, die Bugs an den verrücktesten Stellen häufen sich - damit will niemand arbeiten.
Das mag vielleicht ein Extrembeispiel sein, aber das Prinzip bleibt: Selbst entwickelte Frameworks stellen eine enorme Gefahr dar, wenn sie nicht gut durchdacht sind.

C
CoPyMaus Themenstarter:in
12 Beiträge seit 2021
vor 2 Jahren

Hallo Palladin007,

vielen Dank für deinen Beitrag. Ich komme leider erst jetzt dazu, mich der Sache weiter zu widmen und werde natürlich deine Lösungsansätze ausprobieren.

OnContentRendered & StackPanel_MouseDown:
Für Beides gibt es meines Wissens nach keine direkte Lösung mittels Commands, das Prinzip funktioniert aber trotzdem, ...
... Besser wäre natürlich, Du verzichtest ganz auf CodeBehind, in den allermeisten Fällen geht das und Du kommst nicht auf die idee, irgendwelche Logik hineinzuschreiben.

Das ist einer meiner Ziele: Komplett ohne Code-Behind auszukommen. Nur habe ich bisher noch keine Lösungen gefunden. Dafür jedoch, das ich ein Passwortfeld tausche, gegen ein Textfeld, bei jedem Tastendruck, das eingegebene Zeichen abfange, dieses Zeichen zusammen mit bereits vorhandenen Zeichen, in ein anderen String lege und dem Field einfach nur die Anzahl Dots zurück schicke, die bereits in Password.Length vorzufinden sind. War ne nette Idee, die ich hatte und funktioniert super.

Bei beiden Methoden frage ich mich aber auch: wozu?
Das Bewegen eines Fensters verbieten ... ich hasse es!

Ja eben nicht verbieten. StackPanel_MouseDown ermöglicht es wieder, nach einem WindowStyle="None", das Window wieder verschieben zu können. Wichtig ist mir dabei auch, das ich die Positionsdaten (Ecke oben links) des Window beim schließen des Programms habe, um diese in den AppSettings zu speichern. (Wiederherstellung beim Start) Das habe ich alles mit ViewModel ohne Probleme bereits lösen können.

Not-invented-here-Syndrom:
Von mir ein kleiner Erfahrungsbericht, was...

Ok, wenn man auf seiner Arbeit so einen Chef hat, braucht man keine Feinde mehr. Zumindest in Sachen Entwicklung nicht. Ich würde damit vermutlich auch nicht glücklich werden.
Ich verstehe die Situation, das man nicht ganz ohne zusätzliche Libs auskommt. Ich verwende ja auch schon das Newtonsoft.Json, weil es meines Erachtens, besser mit PHP kompatibel ist. Ja, das Programm synchronisiert Daten mit der HP ab. Auch was Styles anbelangt, musste ich bereits auf das PresentationFramwork.Aero zurück greifen, da ich sonst meine ComboBoxen nicht so hinbekommen hätte, wie ich es wollte.

Was ich damit sagen möchte: Wenn es wirklich nicht anders geht, greife ich selbstverständlich auf externe Libs zurück. Nur will ich vermeiden, das Libs für vielleicht eine oder zwei Methodenaufrufe eingebunden werden, die man hätte elegant auch so lösen können. (Ausnahmen bestätigen die Regel).

Was haltet ihr den von MVVM-Light? Ist es wirklich so Sinnbringend, das man besser nicht darauf verzichten sollte? Oder ist es nur eine Erweiterung, das 0815 Noobs (wie ich noch einer bin) damit besser klar kommen?

CoPyMaus

16.807 Beiträge seit 2008
vor 2 Jahren

Ist es wirklich so Sinnbringend, das man besser nicht darauf verzichten sollte?

Mit Frameworks wie MVVMLight, Prism oder Caliburn hast Du die Chance Not-invented-here-Syndrom zu vermeiden.

Dein Ziel ist es ein Mini-Tool zu schreiben, das gewisse Aufgaben erledigen soll. Klar, Du kannst auch die nächsten Wochen damit verbringen das MVVM Light selbst nachzubauen; am Ende wirst dann mehr Zeit in die MVVM Implementierung stecken als in die Funktionalität Deines Minitools.

Hinweis, den Du wohl noch nicht von der MVVMLight Website entnommen hast:
MVVMLight ist eingestellt bzw. schon vor 2-3 Jahren in das Windows Community Toolkit übergegangen.
Introduction to the MVVM package - Windows Community Toolkit

PS: statt Newtonsoft.Json sollte man mittlerweile System.Text.Json verwenden.
Steht ebenfalls in der Doku 🙂

2.078 Beiträge seit 2012
vor 2 Jahren

Komplett ohne Code-Behind auszukommen. Nur habe ich bisher noch keine Lösungen gefunden.

Das funktioniert mit AttachedProperties oder Behaviors.
Oder Du nutzt Trigger, allerdings gibt's davon drei Varianten: Am Control, Style oder als AttachedProperty aus dem Interactivity-Framework.

StackPanel_MouseDown ermöglicht es wieder, nach einem WindowStyle="None", das Window wieder verschieben zu können

Du willst also ein eigenes Window designen, was es dir ermöglicht, ein Template für z.B. die Kopf-Zeile festzulegen. Für sowas würde ich ein CustomControl nutzen, das von Window ableitet. Außerdem hast Du so den Code, der für das selbst designte Window notwendig ist, getrennt vom Rest.

Wenn Du das alles getrennt hast, kannst Du meiner Meinung nach auch CodeBehind nutzen.
MVVM verbietet das ja nicht, es besagt nur, dass Du keinerlei BusinessLogik in der View implementieren sollst.
CodeBehind ist in Ordnung, solange es sich dabei nur um reine View-Logik dreht, also z.B. das Bewegen des Fensters.

Bedenke aber, dass es bereits Frameworks gibt, die sowas schon anbietet, MahApps zum Beispiel 😉
MahApps kann auch noch sehr viel mehr, wenn das Metro-Design für dich eine Option ist, dann würde ich das nutzen.

Wenn es wirklich nicht anders geht, greife ich selbstverständlich auf externe Libs zurück

Es geht nicht darum, ohne Frameworks auszukommen, sondern dass man von der sehr viel umfangreicheren Erfahrung profitieren kann, außerdem sind sie oft sehr ausführlich getestet.
Wenn ich z.B. nur an einer einzelnen Stelle ein kleines JSON mit ein/zwei Properties brauche, würde ich vermutlich auch nur den String zusammen bauen, aber sobald es ein größeres JSON oder dynamisch wird, wird ein Framework genutzt.

Ich verwende z.B. meistens (zumindest wenn möglich) Microsoft.Extension.DependencyInjection, Microsoft.Extension.Configuration, Microsoft.Extension.Logging, etc.
Diese Frameworks brauche ich zwar nicht zwingend, sie erleichtern mir allerdings die Arbeit und liefern eine einheitliche Herangehensweise an häufige Probleme.

C
CoPyMaus Themenstarter:in
12 Beiträge seit 2021
vor 2 Jahren

@Abt

... am Ende wirst dann mehr Zeit in die MVVM Implementierung stecken als in die Funktionalität Deines Minitools.

Von einem Minitool mit ein paar kleinen Funktionen habe ich nicht gesprochen. Viel mehr geht es um eine ServerSoftware, die ShoutCast, IceCast und RSAS vewalten und steuern soll. Des Weiteren beinhaltet es ein User- & GroupManagement, Informationssystem und einem kleinen Chat. Eine zweite Software, die auf die Serversoft zugreift (Client), kann hingegen fast nichts, weil sämtliche Berechtigungen von der ServerSoft bereit gestellt werden. Das bedeutet, der Client wertet nur aus und bietet an. Die Kommandos selber, werden jedoch wieder über die Serversoftware ausgeführt. Natürlich ist die Übertragung zwischen Server und Client verschlüsselt. Außerdem syncronisiert sich die Software mit der Datenbank der Homepage. (Ebenfalls verschlüsselt - Sorry, bin mal Opfer von einer MITM- Attacke geworden. Das hat geprägt.)

Client = Minitool (Das lasse ich so stehen)
Der Server ist meines Erachtens nicht mehr so mini. Da steckt schon einiges hinter. Aber naja, andere mögen es noch als Mini bezeichnen.

@Abt und @Palladin007
Ich möchte euch gegenüber meine Danksagung aussprechen. Ich bin offen für Kritik. Aber auch die Anregungen, die ihr mir mit auf dem Weg gegeben habt, bleiben nicht ungeachtet. Ich werde mein Projekt erst mal für ein paar Tage ruhen lassen, mich in die Materie der von euch vorgeschlagenen Libs einlesen und experimentieren. Im Anschluss werde ich ggfl. mein Projekt noch mal umbauen.

Danke
CoPyMaus