Ok meine Architektur sieht folgendermassen aus. Ich habe eine Windows.Form Anwendung und eine DLL mit meinen Klassen.
Da ich aber die WPF Techniken nutzen möchte, habe ich eine 3tes Projekt erstellt, in dem die WPF Controls enthalten sind.
Das Windows Form hat bisher immer UserControls in dem Form ausgetauscht. Damit ich nun WPF Controls einbinden kann, enthalten die UserControls nur noch die Logik und über ein ElementHost wird das WPF Control dargestellt.
Ich sehe es theoretisch genauso, dass die WPF Controls default-Aussehen haben.
Nur wie kann ich über meine Anwendung definieren wie die Styles von den Controls sind. Das Problem ist, dass auf dem WPF Control verschiedene Controls vorhanden sein können, die auch wiederrum WPF Controls beinhalten usw.
Wie kann sowas sauber realisiert werden?
EDIT:
Ok nehmen wir an ich mappe die Styles von den Untercontrols auf dem WPF Controls auf public Properties. Dann hätte ich noch immer das Problem, das ich von einer Windows.Form Anwendung auf kein ResourceDictionary zugreifen kann. Erstellen kann ich dies ja leider dort auch nicht.
Diese, ich nenne sie LayoutManager (Grid, Canvas) haben ein unterschiedliches Verhalten. Sie sind für Unterschiedliche Zwecke gedacht.
Um ein ähnliches Verhalten wie Anchor zu nutzen, empfehle ich dir ein Grid. Ein Canvas ist eher für eine absolute Positionierung gedacht.
Leider ist WPF durch einen enormen Funktionszuwachs auch komplzierter geworden. So ist es aber immer. Umso mehr Möglichkeiten man haben möchte, umso schwerer ist es somit auch, das Beste für sich zu finden.
<Image.Triggers>HIER</Image.Triggers> 🙂
Triggers kommt vom FrameworkElement.
Ich habe zwar nicht verstanden wieso das so ist, aber ich nehme es einfach mal so hin.
Vielen Dank für deine Hilfe.
Vielen Dank.
... Wenn du nun die ItemsSource setzt, dann befindet sich in der Items-Auflistung eine Collection deiner Objekte.
Ok, also kann ich mir das folgendermassen vorstellen. Mein ListViewItem hat ein Child, welches mein Item aus dem Source entspricht. In meinem ControlTemplate bin ich auf der Ebene des Childs und kann deshalb mit Binding auf die Eigenschaften von meinem Typ zugreifen. Um nun wieder zu meinem Parent (dem ListViewItem) zu gelangen, muss ich TemplateBinding nutzen?
Habe mir das so hergeleitet, da Template Binding {Binding RelativeSource={RelativeSource TemplatedParent}} laut MSDN entspricht.
Erstelle dir eine Methode/Eigenschaft, welche dir den Gesamtpfad zurückgibt und diesen bindest du dann einfach.
Schade, dass soetwas nur so umständlich ist. Eine Möglichkeit wie Key="Mein Statischer Wert {Binding ...}" wäre viel praktischer 🙂
Dein UserControl ist ja auch nur ein Element. Probiere es mit einem Binding unter Angabe des ElementName und verweise auf deine entsprechende Property. Achte darauf, dass es sich um eine DependencyProperty handelt. Das sollte funktionieren, ohne es jetzt getestet zu haben.
In dem Fall dürfte ich das Template aber nicht in ein ResourceDictionary auslagern, da zu dem Zeitpunkt der ElementName noch garnicht exisiert, bzw. nicht bekannt ist, dass er jemals existieren wird. Somit kann ich wieder nicht wirklich Design zentral verwalten.
Eine Skinfähigkeit unter WPF durchzusetzen, ist meiner Meinung nach nicht einfacher als bei Windows Forms, leider 🙁
Vielen Dank. Genau soetwas hatte ich gesucht.
Falls du die Zeit findest, wäre es echt toll, wenn du noch meinen vorherigen Beitrag beantworten könntest.
Nocheinmal vielen Dank.
Und zwar: Durch das ControlTemplate legst du ja fest, für welchen Typ es zuständig ist bzw. in welchem Typ es verwendet wird. Dieser Typ IST ein ListViewItem. Dieses bietet Eigenschaften an, die verwendet werden können (IsSelected zum Beispiel).
Nun fügst du eigene Objekte der Items-Auflistung hinzu (DataSource, wie auch immer). Diese werden für das DataBinding verwendet, d.h. er findet so auch den angegebenen Pfad, weil pro ListViewItem auf das Objekt geachtet wird, das darin enthalten ist.
Das heisst also, ich kann sowohl "{Binding Path=EigenschaftMeinesTyp}" und "{Binding Path=EigenschaftListView}" nutzen?
Du hast geschrieben "Dieser Typ IST ein ListViewItem". Das ControlTemplate bezieht sich doch genau auf ein Item und das kann doch nur von einem Typ sein. Ich verstehe die Logik irgendwie nicht. Befinde ich mich in einem ListViewItem oder in einem Item von meinem Typ? Ich stelle mir das so vor, dass ich mich in dem Design Bereich einer foreach Schleife befinde. Ich hoffe du verstehst was ich meine.
Du kannst das über einen ObjectDataProvider in deinen Ressourcen machen und da das Ergebnis einer Methode etc. binden.
Ok danke, aber in dem Fall kann ich nun nur an den Pfad binden. Ich möchte aber sozusagen den Sourcestring aus 2 Bindungen zusammensetzen. D.h. sowas wie Pfad (Bindung1) + Dateiname (Bindung2).
Ich versuche die Zeit zu finden, dir da ein Beispiel zu erstellen.
Das wäre super.
Eine Kleinigkeit ist mir auch noch unklar. Wenn ich mich in dem ControlTemplate befinde, habe ich nur einen Bezug auf ein ListViewItem. Dieses ControlTemplate nutze ich in einem UserControl. Was ist aber wenn ich aus dem ControlTemplate auf Eigenschaften des UserControls zugreifen möchte. Ich habe da folgendes Problem. Mein UserControl hat eine Eigenschaft DefaultImageSource. Wenn kein ImagePath in meinen Items vorhanden ist, soll dieser DefaultImageSource genutzt werden. Meine Idee in der Sache wäre ein Trigger, der ja (wahrscheinlich) auf die Eigenschaften des Items zugreifen kann. Aber wie sag ich dem Trigger dann, dass er den ImageSource Pfad in dem Fall auf DefaultImageSource setzen soll?
Ersteinmal vielen Dank, das du dir das angeschaut hast.
EDIT:
Die Items gehen über den Source in das ListView als BindingList<>
1 u. 2) So ganz ist es mir nicht. Ich greife doch zB im Trigger auf Eigenschaften von ListViewItem (IsSelected) zu und binde auf der anderen Seite an Member von meinem Typ (ElementContent).
Ich habe z.B. eine statische Eigenschaft in einem Singleton Objekt. In meinem Fall habe ich z. B. einen Pfad. Nun möchte ich gerne den ImageSource setzen, Pfad (nicht im Item vorhanden) + Dateiname. Wobei der Dateiname in dem Item vorhanden ist.
D.h. um z.B. im ControlTemplate die Breite eines Image(Containers) per Trigger zu ändern, müsste ich diese Eigenschaft an eine (Dummy) Eigenschaft des Items binden?
Nun sind wir aber bei Problem 1 u. 2. Im Trigger kann ich doch nur auf die Eigenschaften von ListViewItem und nicht meinem Typ zugreifen.
EDIT: Ich möchte z. B. bei nem IsSelected eine Animation starten oder so.
Das ist der aktuelle Stand. Dabei geht es auch mehr um das Verständis der Sache.
Das komplette Projekt würde den Umfang sprengen.
Bitte les dir vorallem meinen 2ten Beitrag und die darin enthaltenen vorhanden Fragen durch. Dann verstehst du was ich grundlegend nicht verstehe.
Eine App.xaml habe ich ja leider nicht (DLL) und bringt bei den Controls auch nichts.
Bei den Styles werden selbst die "primitiven" Controls wie z.B. Button oder Labels angesprochen.
Wenn man hört wie toll, WPF ist, wird oft gesagt:
"Man kann Styles definieren und dafür sorgen, dass alles gleich aussieht"
So einfach ist es aber nicht, dies ist nur die halbe Wahrheit. Wieso gibt es dafür keine "globale" Lösung für eine komplette DLL.
Wäre es nicht schön, für ein Namespace ressourcen hinterlegen zu können 🙂
Wenn dazu noch die Funktionaliät von partiellen XAML Files existieren würde, wären meine Probleme gelöst.
Und genau zu diesem Zeitpunkt, wäre die Aussage "Man kann Styles definieren und dafür sorgen, dass alles gleich aussieht" für mich auch wahr.
Wieso kann man Styles nicht genauso wie Klassen betrachten. Somit könnte man die Styles ohne Probleme einbinden und auch viel kompfortabler davon ableiten.
Für mich ist die Sache ein unnötiger riesen Verwaltungsaufwand und ist auch für eine Erweiterbarkeit nicht sonderlich hilfreich.