WPF | Binding innerhalb eines Attached DependencyProperty
-
Ich möchte ein AttachedProperty erstellen, welches eine Auflistung von anderen bereits existenten Elementen enthält. Im Beispiel unten habe ich es auf eine Referenz (zu "myButton") beschränkt.
<Window x:Class="myNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:myNamespace"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <ContentPresenter> <ContentPresenter.Content> <Button> <local:DependencyObjectCollectionHost.Objects> <local:DependencyObjectCollection> <local:DependencyObjectContainer Object="{Binding ElementName=myButton}"/> </local:DependencyObjectCollection> </local:DependencyObjectCollectionHost.Objects> </Button> </ContentPresenter.Content> </ContentPresenter> <Button Grid.Row="1"/> </Grid> </Window>
Um das überhaupt möglich zu machen, habe ich eine generische Container-Klasse erstellt, welche ein Property "Object" besitzt, mit dem ich ein Binding auf ein anderes Element setzen kann.
public class ObjectContainer<T> : DependencyObject where T : DependencyObject { static ObjectContainer() { ObjectProperty = DependencyProperty.Register ( "Object", typeof(T), typeof(ObjectContainer<T>), new PropertyMetadata(null) ); } public static DependencyProperty ObjectProperty; [Bindable(true)] public T Object { get { return (T)this.GetValue(ObjectProperty); } set { this.SetValue(ObjectProperty, value); } } } public class DependencyObjectContainer : ObjectContainer<DependencyObject> { } public class DependencyObjectCollection : Collection<DependencyObjectContainer> { } public static class DependencyObjectCollectionHost { internal const string ObjectsPropertyName = "Objects"; static DependencyObjectCollectionHost() { ObjectsProperty = DependencyProperty.RegisterAttached ( "Objects", typeof(DependencyObjectCollection), typeof(DependencyObjectCollectionHost), new PropertyMetadata(null, OnObjectsChanged) ); } public static DependencyObjectCollection GetObjects(DependencyObject dependencyObject) { return (DependencyObjectCollection)dependencyObject.GetValue(ObjectsProperty); } public static void SetObjects(DependencyObject dependencyObject, DependencyObjectCollection value) { dependencyObject.SetValue(ObjectsProperty, value); } public static readonly DependencyProperty ObjectsProperty; private static void OnObjectsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { var objects = (DependencyObjectCollection)e.NewValue; if (objects.Count != objects.Count(d => d.Object != null)) throw new ArgumentException(); } }
Leider funktioniert das nicht. Die Objekt-Eigenschaft ist immer "null". Ich denke es liegt daran, dass dem Binding der DataContext fehlt und somit das Element nicht gefunden werden kann. Außerdem ist es nicht Teil des VisualTrees, was hier ebenfalls nötig wäre. Jedoch fällt mir keine Lösung dazu ein. Eine eigene ICollection Klasse erstellen, die von FrameworkElement erbt?
Hat jemand eine Idee? Besten Dank im Voraus.