WPF - Bindung eine ObservableCollection Abhängigkeit Eigenschaft in einem UserControl
Habe ich eine Kontrolle
Klasse DragGrid : Grid
{
...
}
welche erbt von der ursprünglichen raster und ermöglicht ziehen und ändern der Größe Ihrer untergeordneten Elemente.
Ich muss zum binden eines benutzerdefinierten DP benannt WorkItemsProperty
eine observable-collection von Typ WorkItem
(implementiert INotifyPropertyChanged
). Jedes element im raster gebunden ist, zu einem sammelelement.
Immer, wenn der Benutzer fügt ein neues Element dynamisch zur Laufzeit (die posten können in XAML deklariert werden!), oder löscht ein Element aus der Auflistung, die WorkItems
DP auf der DragGrid aktualisiert werden soll, und die Kinder in der Tabelle (wo jedes Kind steht ein WorkItem
Sammlung Element).
Meine Frage ist, wie kommt der DP Benachrichtigen Sie die Kontrolle über das Kind-element in das raster muss entfernt, geändert ('change' bedeutet, dass der Benutzer ein element gezogen oder Größe mit der Maus) oder Hinzugefügt, und wie würde ich erkennen, welche eines der vorhandenen Kinder ist das, was muss gelöscht oder geändert werden.
Ich verstehe, dass dies ist, wo die DependencyPropertyChangedCallback kommt. Aber, dass nur aufgerufen wird, wenn die DP-Eigenschaft festgelegt ist neu, nicht wenn etwas in der Sammlung-änderungen (wie add, remove-item). Also am Ende, hat die DragGrid
Kontrolle irgendwie, die Sie abonnieren müssen, um das CollectionChanged-Ereignis? An welchem Punkt würde ich Haken der event-handler für das?
*EDIT::
Der Grund für die Verwendung eines Rasters in der ersten Ort ist, denn ich möchte in der Lage sein, um die Aufrechterhaltung eines minimalen delta für, wenn der Benutzer oder die Größe des Steuerelements in der Startaufstellung. Eine Steuerung stellt eine Zeit-Spanne, und jede grid-Spalte repräsentiert 15min (das ist der minimale Wert). Tun dies in einer Leinwand mit den Daumen war schwierig und fehlerhaft. Die Implementierung eines DragGrid gelöst meine Benutzer-Interaktions-Probleme. Auch eine Leinwand ist nicht skalierbar, so dass die Zeitspannen, müsste neu berechnet, die ganze Zeit. Mit dem Raster habe ich nicht das problem, da die Spalten, die mir die Zeit egal, die Größe.**
Du musst angemeldet sein, um einen Kommentar abzugeben.
Antwort auf deine eigentliche Frage:
Sollten Sie einen DepencyPropertyChanged-handler, wie Sie bereits erwähnt. In dieser Prozedur ist, sollten Sie fügen Sie einen Ereignishandler für das CollectionChanged-Eigenschaft auf die neue Kollektion und entfernen Sie den handler aus der alten Sammlung, wie diese:
Als gehho erklärte, es klingt wie Sie nicht mit der Grid-Klasse, wie ursprünglich vorgesehen, obwohl Sie vielleicht zu weit in der Entwicklung zu beginnen möchten Sie an dieser Stelle. Klassen abgeleitet von Panel sind eigentlich nur dafür gedacht, um visuell zu zeichnen/anordnen Ihre Kinder, anstatt die Manipulation und Veredelung. Check-out ItemsControl und die WPF-Content-Modell, um mehr zu erfahren.
Sorry, ich habe keine Lösung für Ihre konkrete custom
Grid
problem, aber ich habe nur einen Vorschlag, wie Sie tun können, es einfacher (und, ich nehme an, wie es gemeint ist von den WPF-Designer). Eigentlich einGrid
ist nicht eine Kontrolle zu veranlassen Elemente. Es ist einPanel
ordnet dieControls
. Also, ich glaube, das ist (einer) der Grund(Gründe) warum Sie immer in Schwierigkeiten mit Ihrer Lösung.Was ich verwenden würde, stattdessen ist ein
ItemsControl
(z.B. einListBox
) mit einemCanvas
alsItemsPanel
.Nun definieren Sie die entsprechenden Eigenschaften in Ihrem
WorkItem
(oderWorkItemViewModel
) Klasse wieXPos
undYPos
werden Datenbindung, um dieCanvas.Left
undCanvas.Top
Eigenschaften wie dieses:Dann können Sie dieses Element Stil durch die Zuordnung der
ItemContainerStyle
Eigenschaft desListBox
:Ich weiß nicht, wie die Umsetzung der drag-and-drop Zeug, weil ich das noch nie gemacht haben, aber offensichtlich haben Sie es bereits getan für Ihre benutzerdefinierte
Grid
, so sollte es nicht ein großes problem, um es in einerListBox
als gut. Allerdings, wenn Sie aktualisieren Sie die Eigenschaften IhrerWorkItem
sollte es automatisch die Position des element. Auch, wenn Sie hinzufügen/entfernen Artikel zu/von Ihrer Sammlung (WorkItemsProperty
), es werden automatisch Hinzugefügt/entfernt, da dieListBox
ist-Daten an die Sammlung.Müssen Sie möglicherweise ändern Sie Ihre
WorkItemStyle
je nach Szenario. Zum Beispiel, wenn die ListBox in der Größe geändert wird, zur Laufzeit, die Sie haben könnten, um die Positionen relativ zu dem container (Leinwand) Größe. Daher müssten Sie einMultiBinding
statt der einfachenBinding
. Aber das ist eine andere Geschichte...Nun, es ist Ihre Entscheidung, ob Sie sich noch bewegen kann diesem Ansatz ist, oder ob Ihr
Grid
ist fast beendet, und Sie sind nicht bereit sich zu ändern. Ich weiß, es ist hart, aber in meinen Augen, den obigen Ansatz ist das sauberer (und einfacher!) man!