Irgendwelche Ideen zur Implementierung einer Methode, die einen propertyname erhält, finden ein Steuerelement (vielleicht aus einem visualtree), das an die angegebene Eigenschaft gebunden ist?WPF. Suche nach einem Steuerelement, das an eine bestimmte Eigenschaft bindet
Antwort
Versuchen Sie diese. Kopieren Sie zuerst diese DependencyObjectHelper-Klasse in Ihr Projekt. Es verfügt über eine Funktion, mit der Sie alle BindingObjects in einem bestimmten Objekt abrufen können.
public static class DependencyObjectHelper
{
public static List<BindingBase> GetBindingObjects(Object element)
{
List<BindingBase> bindings = new List<BindingBase>();
List<DependencyProperty> dpList = new List<DependencyProperty>();
dpList.AddRange(DependencyObjectHelper.GetDependencyProperties(element));
dpList.AddRange(DependencyObjectHelper.GetAttachedProperties(element));
foreach (DependencyProperty dp in dpList)
{
BindingBase b = BindingOperations.GetBindingBase(element as DependencyObject, dp);
if (b != null)
{
bindings.Add(b);
}
}
return bindings;
}
public static List<DependencyProperty> GetDependencyProperties(Object element)
{
List<DependencyProperty> properties = new List<DependencyProperty>();
MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element);
if (markupObject != null)
{
foreach (MarkupProperty mp in markupObject.Properties)
{
if (mp.DependencyProperty != null)
{
properties.Add(mp.DependencyProperty);
}
}
}
return properties;
}
public static List<DependencyProperty> GetAttachedProperties(Object element)
{
List<DependencyProperty> attachedProperties = new List<DependencyProperty>();
MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element);
if (markupObject != null)
{
foreach (MarkupProperty mp in markupObject.Properties)
{
if (mp.IsAttached)
{
attachedProperties.Add(mp.DependencyProperty);
}
}
}
return attachedProperties;
}
}
Dann erstellen Sie diese GetBindingSourcesRecursive Funktion. Es sammelt rekursiv die DependencyObjects in der visuellen Struktur, die mindestens ein Binding-Objekt aufweist, das auf einen bestimmten Eigenschaftsnamen abzielt.
private void GetBindingSourcesRecursive(string propertyName, DependencyObject root, List<object> sources)
{
List<BindingBase> bindings = DependencyObjectHelper.GetBindingObjects(root);
Predicate<Binding> condition =
(b) =>
{
return (b.Path is PropertyPath)
&& (((PropertyPath)b.Path).Path == propertyName)
&& (!sources.Contains(root));
};
foreach (BindingBase bindingBase in bindings)
{
if (bindingBase is Binding)
{
if (condition(bindingBase as Binding))
sources.Add(root);
}
else if (bindingBase is MultiBinding)
{
MultiBinding mb = bindingBase as MultiBinding;
foreach (Binding b in mb.Bindings)
{
if (condition(bindingBase as Binding))
sources.Add(root);
}
}
else if (bindingBase is PriorityBinding)
{
PriorityBinding pb = bindingBase as PriorityBinding;
foreach (Binding b in pb.Bindings)
{
if (condition(bindingBase as Binding))
sources.Add(root);
}
}
}
int childrenCount = VisualTreeHelper.GetChildrenCount(root);
if (childrenCount > 0)
{
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(root, i);
GetBindingSourcesRecursive(propertyName, child, sources);
}
}
}
Dann wird diese zu verwenden, rufen Sie einfach GetBindingsRecursive in dem Eigenschaftsnamen vorbei, die Wurzel visuelle (zum Beispiel das Fenster), und eine Objektliste, die die Ergebnisse enthält.
List<object> sources = new List<object>();
GetBindingSourcesRecursive("SomePropertyPath", this, sources);
sources.ForEach((o) => Console.WriteLine(o.ToString()));
Hoffe das hilft.
Ich erstellte Code basierend auf angenommenen ASanch Antwort. Dieser Code verwendet LogicalTreeHelper, der es sechsmal schneller macht (130ms gegenüber 20ms, wenn nach Kontrolle mit spezifischer Bindung für ein einfaches Fenster gesucht wird).
Plus I einige Fehler in ASanch Code zu beheben (siehe original "else if (Bindingmultibinding ist)" oder "else if (Binding ist Priority)").
public static class DependencyObjectHelper
{
/// <summary>
/// Gets all dependency objects which has binding to specific property
/// </summary>
/// <param name="dependencyObject"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
public static IList<DependencyObject> GetDependencyObjectsWithBindingToProperty(DependencyObject dependencyObject, string propertyName)
{
var list = new List<DependencyObject>();
GetDependencyObjectsWithBindingToPropertyRecursive(propertyName, dependencyObject, list);
return list;
}
/// <summary>
///
/// </summary>
/// <param name="propertyName"></param>
/// <param name="dependencyObject"></param>
/// <param name="sources"></param>
/// <remarks>
/// Based on ASanch answer on http://stackoverflow.com/questions/3959421/wpf-find-control-that-binds-to-specific-property
/// </remarks>>
private static void GetDependencyObjectsWithBindingToPropertyRecursive(string propertyName, DependencyObject dependencyObject, ICollection<DependencyObject> sources)
{
var dependencyProperties = new List<DependencyProperty>();
dependencyProperties.AddRange(MarkupWriter.GetMarkupObjectFor(dependencyObject).Properties.Where(x => x.DependencyProperty != null).Select(x => x.DependencyProperty).ToList());
dependencyProperties.AddRange(
MarkupWriter.GetMarkupObjectFor(dependencyObject).Properties.Where(x => x.IsAttached && x.DependencyProperty != null).Select(x => x.DependencyProperty).ToList());
var bindings = dependencyProperties.Select(x => BindingOperations.GetBindingBase(dependencyObject, x)).Where(x => x != null).ToList();
Predicate<Binding> condition = binding => binding != null && binding.Path.Path == propertyName && !sources.Contains(dependencyObject);
foreach (var bindingBase in bindings)
{
if (bindingBase is Binding)
{
if (condition(bindingBase as Binding))
sources.Add(dependencyObject);
}
else if (bindingBase is MultiBinding)
{
if (((MultiBinding)bindingBase).Bindings.Any(bindingBase2 => condition(bindingBase2 as Binding)))
{
sources.Add(dependencyObject);
}
}
else if (bindingBase is PriorityBinding)
{
if (((PriorityBinding)bindingBase).Bindings.Any(bindingBase2 => condition(bindingBase2 as Binding)))
{
sources.Add(dependencyObject);
}
}
}
var children = LogicalTreeHelper.GetChildren(dependencyObject).OfType<DependencyObject>().ToList();
if (children.Count == 0)
return;
foreach(var child in children)
{
GetDependencyObjectsWithBindingToPropertyRecursive(propertyName, child, sources);
}
}
}
- 1. WPF - Image-Eigenschaft an Image-Steuerelement binden
- 2. Suche nach einem Objektdiagramm Tree-View-Steuerelement für WPF
- 3. (WPF) Zwei Klassen an ein Steuerelement binden
- 4. die Suche nach einem WinForms-Steuerelement, das Zeitwert
- 5. Wie bindet man die Eigenschaft eines Controls an ein anderes?
- 6. WPF-Steuerelement, das eine 2D-Dimension rendert?
- 7. Komplexes Modell, das an eine Liste bindet
- 8. WPF, das mehrere Steuerelemente an verschiedene Datenkontexte bindet
- 9. Wie man Lenker an willkürliche Eigenschaft bindet?
- 10. JavaFX bindet Auswahlbox an eine Eigenschaft in einer Sammlung
- 11. WPF - Wie bindet man Artikel in DataTemplate?
- 12. An eine bestimmte Eigenschaft von Objekten in einem Array binden
- 13. Implementieren Sie SelectedValues-Eigenschaft auf WPF-Steuerelement
- 14. WPF Hinzufügen einer benutzerdefinierten Eigenschaft in einem Steuerelement
- 15. WPF Ausblenden auf einem Steuerelement
- 16. WPF: Wie an eine geschachtelte Eigenschaft binden?
- 17. Wie bindet JMX eine bestimmte Schnittstelle?
- 18. DataTable, das nach Verwendung von ImportRow nicht an GridView bindet
- 19. WPF-Triggerbindung an MVVM-Eigenschaft
- 20. Suche nach Kontrolle innerhalb von WPF itemscontrol
- 21. Löschen eines Bildes, das von einem WPF-Steuerelement verwendet wurde
- 22. WPF: Mehrere benutzerdefinierte Steuerelement benachrichtigt werden, wenn eine Eigenschaft ändern
- 23. Wie bindet man eine Liste an dataGridView?
- 24. Silverlight MVVM, das eine ListBox bindet
- 25. Auf der Suche nach einem .NET "Text" -Editor Steuerelement
- 26. WPF - Bindung an eine Eigenschaft eines benutzerdefinierten Objekts, das sich in einem anderen Objekt befindet
- 27. TemplateBinding bindet nicht an die Eigenschaft von effect?
- 28. binden eine Benutzersteuerung auf das Gegenteil von einem Bool-Eigenschaft
- 29. Binden Sie eine Eigenschaft an ein benutzerdefiniertes Steuerelement
- 30. Suchen Sie das übergeordnete Steuerelement nach Name
Die Leistung Ihres Codes ist großartig! –