Custom Zeichenoberfläche Unterschied C# und VB

  • WPF

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Dreiecke werden über eine Reference an den Knoten gebunden und der Knoten wird an das Canvas gebunden.

    ​Vierecke nehmen die Koordinaten des Knotens her (indem Node.PropertyChanged aboniert wurde) berechnen sich ihre eigenen Koordinaten und binden direkt an das Canvas.

    Schau mal in Post Nr. 9 habe ich des genauer ausgeführt
    Jo - diesen feinen Unterschied hatte ich auch nicht verstanden:

    SKeks schrieb:

    1. Ich setze eine Referenz im ViewModel auf den Knoten und binde über die Knotenkoordinaten an das Canvas...
    2. Ich setze auch hier eine Referenz auf einen zugehörigen Knoten...
    Aber jetzt habe ich verstanden: Die 3-Ecke haben in wirklichkeit die Koordinaten {0, 0}, und nur über eine Art Hack mitte Margins erscheinen sie bei die Kringels.
    Also mir gefällt besser, was die 4-Ecke machen.

    Eine weitere Möglichkeit wäre ein Viewmodel, wo die Kombination Kringel-EckFigur als ein Element aufgefasst wird, nicht als 2 verschiedene, von denen das 2. dem ersten nachgeführt wird.
    Hi,

    Solange ein Objekt nur an einen Knoten gebunden wird ist es recht einfach (siehe Vierecke).

    Es soll aber auch noch Linien geben, die 2 Knoten miteinander verbinden (Line bindet an (X1,Y1) und (X2,Y2) also 2 Knoten und deren Koordinaten). Da wird das Ganze echt häßlich. Vor der Idee aus Post 19 hatte ich mit lokalen Koordinaten rumprobiert, also ein neues, lokales Canvas, welches auf die Zeichenfläche bindet mit

    Quellcode

    1. Zeichenfläche.Left=Math.min(Node1.X, Node2.X)
    2. Zeichenfläche.Top = Math.min(Node1.Y, Node2.Y)

    und auf dem lokalen Canvas dann eine Linie (diese bindet über 2 Punkte) welche sich dann berechnen zu

    Quellcode

    1. Startpoint.X = Node1.X
    2. Startpoint.Y = Node1.Y

    Quellcode

    1. EndPoint.X = Node2.X - Node1.X
    2. EndPoint.Y = Node2.Y - Node1.Y


    Das Ganze hat nur im ersten Quadrant des lokalen Koordiantensystems auf dem Startknoten (positiv X und positiv Y) funktioniert. In den anderen 3 Quadranten kam es zu irgendwelchen Verschiebungen relativ zum Startknoten. Irgendwas hat da nicht ganz mit dem Binding an das globale KoordinatenSystem der Zeichenfläche hingehauen

    SKeks schrieb:

    Solange ein Objekt nur an einen Knoten gebunden wird ist es recht einfach (siehe Vierecke).
    Es soll aber auch noch Linien geben, die 2 Knoten miteinander verbinden
    Mir scheint, was du darstellen willst, ist inne Mathematik als "Graph" bekannt.
    Das erfordert ein entsprechendes Viewmodel, und weitere "Objekte". Inne Mathematik spricht man beim Graphen von Knoten und Kanten - und entsprechend musste halt modellieren.
    Für Linien habich in meiner Übung im Viewmodel eine PathGeometry gehalten, daran dann im Xaml ein Path-Objekt gebunden ganz problemlos.

    Aber ich hab keinen Graphen modelliert, sondern ich wollte nur die PathGeometry visualisieren.

    Das Viewmodel eines Graphen muss halt ein Graph sein: Es muss eine Liste von Knoten geben, und eine Liste von Kanten, und jede Kante verweist auf 2 Knoten - was sonst?

    Die Geschichte mit lokale Canvasse gefällt mir nicht - modelliere nach der Wirklichkeit, wie sie ausse Mathematik gut bekannt ist:
    Ein Graph besteht aus einer Liste von Knoten und einer Liste von Kanten.

    Auch die Geschichte mit dem Positionieren via Margin-Property gefällt mir nicht. Eine Position ist X und Y - ein Margin ist was anneres. Und das mit dem Bubbeligen Event unterdrücken scheint mir ein unschöner Workaround, der daraus folgt, dass Margin für was verwendet wird, wasses nicht ist.

    Übrigens habich meine Meinung geändert: Im Sample der Codebehind ist vlt. doch nicht so unangemessen. Ich sagte ja: Bei Dragging kommt auch bei mir MVVM an eine Grenze. Ich mach das zwar immer noch Codebehind-frei, aber um den Preis, dass ich statt Viewmodel ins Codebehind zu packen, mir die View-Elemente ins Viewmodel hole.
    Im Sample, im Codebehind ja auch ein ToDo-Kommentar, dass man dem Codebehind durch lauter Commands und Gedöhns entgehen könne - aber hab ich mal probiert, und solch bläht den Code sowas von auf... - dann lieber doch gegen MVVM sündigen.
    Das Problem ist halt, dass beim Draggen so viele Visuals und Visual-Events beteiligt sind und sein müssen. Das muss iwie mit dem Viewmodel verheiratet werden, und einen der 3 Tode müssemer sterben:
    Entweder a) View ins Viewmodel holen, oder b) Viewmodel ins View, oder c) mit Command-Gedöhns rumfuhrwerken bis zum Abwinken.

    ErfinderDesRades schrieb:

    Mir scheint, was du darstellen willst, ist inne Mathematik als "Graph" bekannt.
    Das erfordert ein entsprechendes Viewmodel, und weitere "Objekte". Inne Mathematik spricht man beim Graphen von Knoten und Kanten - und entsprechend musste halt modellieren.
    Für Linien habich in meiner Übung im Viewmodel eine PathGeometry gehalten, daran dann im Xaml ein Path-Objekt gebunden ganz problemlos.Aber ich hab keinen Graphen modelliert, sondern ich wollte nur die PathGeometry visualisieren.


    ​Im ViewModel ist es so modelliert. Es geht mir rein um die visuelle Darstellung. Soweit ich mich erinnere waren aber bei dir nur die Knoten anklickbar, aber nicht die Pfade selbst und genau da sitzt der Hase im Pfeffer.

    ​Die Geschichte mit lokale Canvasse gefällt mir nicht - modelliere nach der Wirklichkeit, wie sie ausse Mathematik gut bekannt ist:
    Ein Graph besteht aus einer Liste von Knoten und einer Liste von Kanten.


    Genau so habe ich es aber eben hingekriegt inklusive "RequestBringIntoView"​. Lokale Koordinaten dienen ja nur der reinen Visualisierung an dem Canvas über eine Linie. Im ViewModel bindet die Kante immer noch an 2 Knoten und deren Koordinaten und genau so wird es schlußendlich dem Model übergeben und lustig rumgerechnet.


    Übrigens habich meine Meinung geändert: Im Sample der Codebehind ist vlt. doch nicht so unangemessen. Ich sagte ja: Bei Dragging kommt auch bei mir MVVM an eine Grenze. Ich mach das zwar immer noch Codebehind-frei, aber um den Preis, dass ich statt Viewmodel ins Codebehind zu packen, mir die View-Elemente ins Viewmodel hole.
    Im Sample, im Codebehind ja auch ein ToDo-Kommentar, dass man dem Codebehind durch lauter Commands und Gedöhns entgehen könne - aber hab ich mal probiert, und solch bläht den Code sowas von auf... - dann lieber doch gegen MVVM sündigen.
    Das Problem ist halt, dass beim Draggen so viele Visuals und Visual-Events beteiligt sind und sein müssen. Das muss iwie mit dem Viewmodel verheiratet werden, und einen der 3 Tode müssemer sterben:
    Entweder a) View ins Viewmodel holen, oder b) Viewmodel ins View, oder c) mit Command-Gedöhns rumfuhrwerken bis zum Abwinken.


    ​Genau das denke ich mir auch die ganze Zeit. Was manche Leute für Verrenkungen anstellen um auf Teufel komm raus Codebehind zu vermeiden. Aus 100 Zeilen Codebehind werden dann 1000 Zeilen im ViewModel mit Invoke, Delegates und was weiß ich. Aus dieser Laune heraus entstand dann auch dieser Kommentar nach dem Durcharbeiten von zig Papern und X Blogs, die alle CodeBehind hassen :). Einfache Klicks und Tastendrücke lassen sich ja noch einfach über Commands handeln, aber bei der Mausbewegung habe ich bisher noch keine Lösung.
    ​Mal ganz davon abgesehen: Warum wird dann bei Doppelklick auf ein Event im XAML-Editor Codebehind eingefügt. Ach und dieser XAML-Editor von Visual Studi. dauernd stürzt der ab, braucht immer mindestens einmal Kompilieren bis er die Änderungen im ViewModel hat. Da lobe ich mir doch den CodeEditor für VB oder C.

    So zu meiner Lösung:
    ​Hier das Datatemplate zum Verbinden

    XML-Quellcode

    1. <DataTemplate DataType="{x:Type local:Connector}">
    2. <Canvas>
    3. <Line x:Name="Line" Stroke="Blue" StrokeThickness="3"
    4. X1="0" Y1="0"
    5. X2="{Binding VisualLineEndX}" Y2="{Binding VisualLineEndY}" >
    6. </Line>
    7. </Canvas>


    und hier das zugehörige ViewModel:

    VB.NET-Quellcode

    1. ​Public Class Connector : Inherits DesignerObject
    2. ​.......
    3. Private _drawingX As Double = 0
    4. Public Overrides Property DrawingX As Double
    5. Get
    6. Return _drawingX
    7. End Get
    8. Set(value As Double)
    9. _drawingX = value
    10. OnPropertyChanged("DrawingX")
    11. End Set
    12. End Property
    13. Private _drawingY As Double = 0
    14. Public Overrides Property DrawingY As Double
    15. Get
    16. Return _drawingY
    17. End Get
    18. Set(value As Double)
    19. _drawingY = value
    20. OnPropertyChanged("DrawingY")
    21. End Set
    22. End Property
    23. Private _lineEndX As Double
    24. Public Property VisualLineEndX As Double
    25. Get
    26. Return _lineEndX
    27. End Get
    28. Set(value As Double)
    29. _lineEndX = value
    30. OnPropertyChanged("VisualLineEndX")
    31. End Set
    32. End Property
    33. Private _lineEndY As Double
    34. Public Property VisualLineEndY As Double
    35. Get
    36. Return _lineEndY
    37. End Get
    38. Set(value As Double)
    39. _lineEndY = value
    40. OnPropertyChanged("VisualLineEndY")
    41. End Set
    42. End Property
    43. Private _start As Node
    44. Public Property Start As Node
    45. Get
    46. Return _start
    47. End Get
    48. Set(value As Node)
    49. _start = value
    50. AddHandler _start.PropertyChanged, AddressOf SetNewBindingPoint
    51. OnPropertyChanged("Start")
    52. End Set
    53. End Property
    54. Private _ending As Node
    55. Public Property Ending As Node
    56. Get
    57. Return _ending
    58. End Get
    59. Set(value As Node)
    60. _ending = value
    61. AddHandler _ending.PropertyChanged, AddressOf SetNewBindingPoint
    62. OnPropertyChanged("Ending")
    63. End Set
    64. End Property
    65. .......
    66. Protected Sub SetNewBindingPoint(sender As Object, e As PropertyChangedEventArgs)
    67. SetNewBindingValues()
    68. End Sub
    69. Protected Overridable Sub SetNewBindingValues()
    70. If _start IsNot Nothing Then
    71. DrawingX = _start.DrawingX
    72. DrawingY = _start.DrawingY
    73. VisualLineEndX = _ending.DrawingX - _start.DrawingX
    74. VisualLineEndY = _ending.DrawingY - _start.DrawingY
    75. End If
    76. End Sub
    77. End Class

    ​Ich packe morgen nochmal ein Sample zusammen welches das dann verdeutlicht mit den 2 unterschiedlichen Möglichkeiten.
    ​Meine ganzen Versuche zusammengefasst bleibt zu sagen, dass wenn etwas auf einem Canvas gezeichnet werden soll und dabei selektierbar bleiben soll jedes Objekt eigenständig über Canvas.Left und Canvas.Top binden MUSS. Das heißt auch Linien und Polygone können nicht in DataTemplates über (X1,Y1)(X2,Y2) binden, sondern MÜSSEN zwingend Canvas.Left und Canvas.Top bereitstellen, sonst kommt es eben zu dem lustigen Verhalten des ScrollViewers beim Selektieren.
    Freut mich, dass du aus deiner eigenen Praxis zu so ähnlichen Ansichten gelangst wie ich:
    Manchmal wird codebehind-vermeidung krampfhaft.
    Der Xaml-Editor ist eine jämmerliche Krücke, wenn man Performance und Stabilität mit dem ollen WinForm-Designer vergleicht
    Ich hätte noch ein' 3.: Besonders erstaunlich ist, wie miserabel die Intellisense-Unterstützung bei den Bindings ist, und dass sie oft genug ganz ausbleibt, oder auch falsch berät. Und dass man im Xaml jeden Mist in die Bindings schreiben kann, ohne dass das System mehr Korrekturen bietet, als dass es halt nicht so tut, wie man gedacht hat :thumbdown:
    In olle Winforms ist das nicht so, da kriegt man beim Binden eine sehr begrenzte sinnvolle Auswahl, und mitte Syntax der Bindings muss man sich ühaupt nicht auseinandersetzen, es sei denn, man hat höchst spezielle Spezial-Wünsche.

    Aber mal was anderes - ich find, du drückst dich oft miss- und schwer-verständlich aus.

    SKeks schrieb:

    Genau so habe ich es aber eben hingekriegt inklusive "RequestBringIntoView".
    Heisst das nu, dass deine Lösung nachwievor den "RequestBringIntoView"-Unterdrückungs-Workaround-Hack benötigt?


    SKeks schrieb:

    Im ViewModel bindet die Kante immer noch an 2 Knoten und deren Koordinaten...
    Wenn du "binden an" sagst, so verwendest du damit einen Fachbegriff, der in Wpf der Beziehung von Xaml<->Viewmodel vorbehalten sein sollte.
    Wenn ich recht versteh binden deine LinienVMs nicht an KnotenVMs, sondern sie verweisen darauf. Also jedes Linien-Objekt hat intern 2 Variablen, die auf Knoten verweisen - das ist ja kein Databinding.

    Aber würd mich freuen, wenn du dein Werk denn nochmal einstellst, hab schon paar interessante Details drin gefunden, die ich noch nicht kannte. Hingegen gibts einen Xaml-Fehler mit der CompositeCollection - vlt. kriege ich den ja noch ausgebügelt - oder hast du den garnet?

    Auch kann man die DataSource besser einbringen ins Xaml als bisher. Nutzen wäre, dass der Xaml-Editor wesentlich mehr unterstützen würde beim binden.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Auch kann man die DataSource besser einbringen ins Xaml als bisher.
    Jo, das wäre unbedingt in Angriff zu nehmen, und auch nicht weiter schwierig.
    In Application.Xaml:

    XML-Quellcode

    1. <Application x:Class="Application"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:local ="clr-namespace:UserInterface"
    5. StartupUri="View\MainViewEditor.xaml"
    6. xmlns:my ="clr-namespace:UserInterface">
    7. <Application.Resources>
    8. <local:EditorVM x:Key="Mainmodel"/>
    9. </Application.Resources>
    10. </Application>

    Und in MainviewEditor.Xaml:

    XML-Quellcode

    1. <Window x:Class="MainViewEditor"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local ="clr-namespace:UserInterface"
    7. mc:Ignorable="d"
    8. Title="Interface" Height="800" Width="1000"
    9. x:Name="mainview"
    10. DataContext="{Binding Source={StaticResource Mainmodel}}">
    Du wirst sehen - gleich ist der Xaml-Editor viel freundlicher zu dir.
    Und im Codebehind die Sub New() kann dann weg - der DataContext ist nu ja im Xaml gebunden.

    (Weisst ja: Codebehind ist böse - dazu steh ich nachwievor, und dieser Tip scheints malwieder eindrücklich zu bestätigen ;) )
    Sodele. Im Anhang das Projekt:
    • Ellipsen: Button Ellipse - auf Zeichenfläche klicken - Ellipse sollte in rot erscheinen. Rechtsklick auf Zeichenfläche deselektiert Ellipse - Ellipse in gelb. Ellipse markieren (rot) - nochmal klicken - Maus gedrückt halten und bewegen - Ellipse wird grün und lässt sich Draggen
    • Dreiecke: Button Dreieck - auf eine bereits gezeichnete Ellipse klicken - Dreieck sollte in rot erscheinen, leicht nach unten versetzt
    • Vierecke: Button Viereck - auf eine bereits gezeichnete Ellipse klicken - Viereck sollte in grün erscheinen, linke obere Ecke an der Ellipse
    • Verbindungselemente: Hier gibt es 2 Möglichkeiten
      Button "Right": Zeichnet Verbindungslinien mit lokalen Koordinaten und voll selektierbar. Diese Klasse stellt zum Binding an das Canvas Canvas.Left und Canvas.Top Koordinaten bereit. Button "Right" klicken - auf eine bereits gezeichnete Ellipse klicken - Maus bewegen, eine Linienvorschau in gestrichelt sollte zum Mauszeiger hinführen - Maus über weiterem Knoten, Linie sollte durchsichtig blau sein - Linksklick auf den 2. Knoten - Linie wird gezeichnet in blau. Eine selektierte Linie wird rot.

      Button "Wrong": Zeichnet Verbindungslinie, bei der analog den Dreiecken nur eine Referenz auf Anfangs- und Endknoten gesetzt wird und die als Linie über (X1,Y1)(X2,Y2) direkt auf das Canvas binden. Button "Wrong" klicken - auf eine bereits gezeichnete Ellipse klicken - Maus bewegen, eine Linienvorschau in gestrichelt sollte zum Mauszeiger hinführen - Maus über weiterem Knoten, Linie sollte durchsichtig pink sein - Linksklick auf den 2. Knoten - Linie wird gezeichnet in "HotPink". Eine selektierte Linie wird gestrichelt rosa dargestellt.

    Ein Selektieren der Dreiecke und "Wrong"-Elementen führt zu lustigem verhalten des Scrollviewers.
    Ein Selektieren der Vierecke und "Right"-Elemente führt zum gewünschten Markieren ohne Fehlverhalten.

    Als zusätzliches Schmankerl sind rechts neben der Zeichenfläche noch Datatables, welche das ganze nochmal in Tabellenform für die Knoten und die beiden Elementarten anzeigen. Um zu bewerkstelligen, dass man den zu den jeweiligen Elementen zugehörige Knoten ändern kann, habe ich 2 neue Klassen eingeführt:

    Quellcode

    1. AssignedToNodeObject
    für Objekte, die nur an einen Knoten gezeichnet werden sollen (im Sample keine Datatable für enthalten)

    Quellcode

    1. AssignedToNodesObject
    für Objekte, die zwei Knoten benötigen um gezeichnet zu werden.
    Diese beiden Klassen stellen gewissermaßen Wrapperklassen für die zugeordneten Knoten dar und bewerkstelligen die Umrechnung der Knotenkoordinaten in Binding-koordinaten. Zusätzlich werden beim Ändern der Knoten aus der Datatable Events gefeuert, die die neuen Knoten aus dem EditorVM holen und dann dem Objekt bereitstellen. Passenderweise sind dies die Basisklasse für Vierecke und "Right"Elemente.
    Dies habe ich eingeführt, da ein Ändern von Eigenschaften der referenzierten Knoten ja den Knoten selbst verändert.
    Zum Beispiel:
    Es gibt 3 Knoten mit der Nummer 1, 2, und 3. Ein Element verbindet Knoten 1 und 2. Jetzt möchte ich aber aus der Datatable heraus das Element von Knoten 1 nach 3 verlaufen lassen. Wenn ich jetzt aber den Endknoten in der Datatable von 2 nach 3 verändere, wird der Knoten 2 ja nur umbenannt, da ich nur eine Referenz auf diesen Knoten besitze. Dieses falsche Verhalten ist hier passenderweise auch bei den "Wrong"Elementen im Sample.

    Es ist (noch) keine Fehlerbehandlung für falsche Eingaben in die TextBox der Datatable und für Eingabe von Knotennummer, die nicht existieren, implementiert. Hierzu auch gleich eine neue Frage: Wieso gibt es kein NumericUpDown mehr...

    Kurz zu dem Sample: Ich habe dies aus einem größeren Projekt herausgelöst und zusätzlich aus meinem Archiv mit den falsch programmierten Objekten aus früheren Versuchen erweitert. Der Einfachheit halber nur copypaste, das heißt es hat teilweise viele Codedoppelungen drin. Da ich viele Klassen und Zusammenhänge entfernt habe kann es sein, dass noch Variablennamen und Kommentare auftauchen, die scheinbar sinnlos sind. Ich habe zwar alles soweit durchgeschaut, aber nur für den fall der Fälle wollte ich warnen.
    Dateien
    • UserInterface.zip

      (430,05 kB, 281 mal heruntergeladen, zuletzt: )
    Das mit dem Zuordnen der Knoten zu Kanten löst man gewöhnlich mit ComboboxColumns im Datagrid - also eiglich ein Standard-Problem.
    Im von mir angegebenen Tut kommt auch sowas vor, zumindest ansatzweise.

    Ich guck grade nach dem Fehler in diesen Xaml-Zeilen:

    XML-Quellcode

    1. <CollectionContainer Collection="{Binding DataContext.Rectangles,Source={x:Reference MainView}}"/>
    Ist unterkringelt mit der Notiz "Object reference not set to an instance of an object." - keine Ahnung was er meint.
    Aber ich verstehe die Binding-Syntax auch überhaupt nicht - was soll dieses Source={x:Reference MainView} ?
    Ich hab die Syntax zurückgesetzt auf wie ich sie kenne:

    XML-Quellcode

    1. <CollectionContainer Collection="{Binding Rectangles}"/>
    Und - oh Wunder! - Fehler weg.

    Du kannst nun übrigens anfangen, den Xaml-Designer für dich arbeiten zu lassen: Klickse auf die hier genannte Zeile, geh ins PropertyFenster, klickse auf das gelbe Kästchen neben der Collection-Property, und dann "Create Binding".
    Dort das blöde "custom binding" unchecken, und dann kannst du aus den verfügbaren Bindings was vernünftiges aussuchen.
    Siehe dazu auch Grundlagen - MVVM: "Binding-Picking" im Xaml-Editor
    Zwischenzeitlich hat MS halt das Design verändert, aber das Prinzip geht nachwievor wie im Video vorgeturnt.


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Standard-Problem


    Standard für wen :) Ich bin ja kein hauptberuflicher Programmierer oder Entwickler, ich mache das im Selbststudium weils mir Spaß macht :) Google, Bücher und Foren sind hierbei meine Freunde :)

    Edit zu deinem Edit: Diesen Fehler habe ich nicht.
    Im Gegenteil: Wenn ich die Referenz entferne kommt bei mir der Bindingfehler:

    Quellcode

    1. System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=DataContext.Nodes; DataItem=null; target element is 'CollectionContainer' (HashCode=44287968); target property is 'Collection' (type 'IEnumerable')


    Edit2: mir fällt gerade ein wo diese XAML-Binding Synatx her habe: stackoverflow.com/questions/64…ollection-in-a-view-model

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „SKeks“ ()

    Hallo,

    ich sitze immer noch am Codebehind und einer einfachen Lösung dafür:
    macht es Sinn, statt der ListBox als Zeichenfläche sich ein eigenes Control zu erstellen welches von der ListBox erbt? Ein Vorteil wäre ja, dass alle Properties, die die ListBox in XAML bereitstellt erhalten bleiben und dass so der CodeBehind im MainView.xaml.vb in der VB-Datei verschwindet. Man kann hier dann auch direkt auf MouseEvents reagieren statt irgendwelche Verrenkungen mit RelayCommands anzustellen.
    Ich habe mir das so vorgestellt:

    VB.NET-Quellcode

    1. Public Class DrawingSurface : Inherits ListBox
    2. ' erstmal fast leer, es geht nur ums testen ob alle Funktionen der ListBox vorhanden bleiben
    3. Private Sub DrawingSurface_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
    4. ' do something useful
    5. ​End Sub
    6. End Class


    und in XAML:

    XML-Quellcode

    1. <local:DrawingScrollViewer x:Name="DrawingSurfaceScrollViewer"
    2. HorizontalScrollBarVisibility="Auto"
    3. VerticalScrollBarVisibility="Auto">
    4. <local:DrawingSurface x:Name="DrawingSurface"
    5. <local:DrawingSurface.ItemsSource>
    6. <StaticResource ResourceKey="Col"/>
    7. </local:DrawingSurface.ItemsSource>
    8. <local:DrawingSurface.ItemsPanel>
    9. <ItemsPanelTemplate>
    10. <Canvas IsItemsHost="True"
    11. ClipToBounds="True" />
    12. </ItemsPanelTemplate>
    13. </local:DrawingSurface.ItemsPanel>
    14. </local:DrawingSurface>
    15. </local:DrawingScrollViewer>


    Es funktioniert auf jeden Fall rein vom Code her. Grundsätzlich bleibt allerdings die Menge an Code ja gleich, die man dafür braucht, aber eben CodeBehind der MainView wäre halt leerer.

    Viele Grüße

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SKeks“ ()