Jakieś pomysły dotyczące implementacji metody, która nadała nazwę właściwości, znajduje element sterujący (być może z wizualnego), który jest powiązany z daną właściwością?WPF. Znajdź formant, który wiąże się z określoną właściwością.
Odpowiedz
Wypróbuj tę. Najpierw skopiuj i wklej tę klasę DependencyObjectHelper do swojego projektu. Ma funkcję, która pozwala uzyskać wszystkie BindingObjects w danym obiekcie.
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;
}
}
Następnie należy utworzyć ten GetBindingSourcesRecursive funkcję. Rekursywnie gromadzi obiekty DependencyObjects w drzewie wizualnym, które ma co najmniej jeden obiekt wiążący, który ma przypisaną nazwę właściwości.
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);
}
}
}
Następnie, aby to wykorzystać, po prostu zadzwoń GetBindingsRecursive przekazując nazwy właściwości, korzeń wizualny (np okna), oraz listę obiekt, który będzie zawierał wyniki.
List<object> sources = new List<object>();
GetBindingSourcesRecursive("SomePropertyPath", this, sources);
sources.ForEach((o) => Console.WriteLine(o.ToString()));
Mam nadzieję, że to pomoże.
Utworzono kod na podstawie zaakceptowanej odpowiedzi ASanch. Ten kod używa LogicalTreeHelper, który sprawia, że jest 6 razy szybszy (130ms vs 20ms przy szukaniu kontroli ze specyficznym wiązaniem w prostym oknie).
Plus naprawić niektóre błędy w kodzie ASanch (spojrzeć na oryginalny "else if (bindingBase jest MultiBinding)" lub "else if (bindingBase jest PriorityBinding)").
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. Znajdź formant w loginview
- 2. Znajdź domyślną fazę, którą wtyczka Maven wiąże się z
- 3. WPF: jak powiązać z właściwością zagnieżdżoną?
- 4. Jak mogę powiedzieć, że moje DataTemplate wiąże się z właściwością w PARENT ViewModel?
- 5. Konfigurowanie powiązania z niestandardową właściwością DependencyProperty wewnątrz formantu użytkownika WPF
- 6. Znajdź formant w Windows Forms o nazwie
- 7. WPF Datagrid RowDetailsWskazówkaTemplate związana z właściwością
- 8. WPF: Wiązanie etykiety z właściwością klasy
- 9. WPF DataGrid wiąże się string.length zamiast tekstu strun
- 10. WPF powiązanie właściwości usercontrol z rodzicielską właściwością
- 11. Prototyp: znajdź wszystkie elementy z określoną klasą?
- 12. Znajdź element, który pojawia się raz.
- 13. Jak przekonwertować formant WPF na obraz?
- 14. Sekwencjonowanie wiąże się z czystymi funkcjami
- 15. WPF CheckBox TwoWay nie wiąże pracy
- 16. WPF DataGrid RowDetails Widoczność powiązania z właściwością (tylko z XAML)
- 17. Jak mogę się dowiedzieć, który klejnot ma określoną zależność?
- 18. się na UIButton z właściwością tag IPhone
- 19. Menu kontekstowe WPF nie wiąże się z właściwym obiektem danych pozycji
- 20. Problemy wirtualizacji Wpf DataGrid podczas wiązania z właściwością DataGridRow.IsSelected
- 21. WPF znajdź kontrolkę
- 22. Czy istnieje formant WPF, który wyświetli listę plików w widoku podobnym do Eksploratora?
- 23. WPF - powiązanie z jawnie zaimplementowaną właściwością interfejsu z kodu za/dołączonym zachowaniem
- 24. Angular 2-komponentowy DOM wiąże się z właściwością w komponencie, zanim rozwiązana zostanie fasola w metodzie OnInit.
- 25. Adorner WPF przekształca się
- 26. Jak mogę sprawdzić, czy obiekt z określoną właściwością istnieje w tablicy Ruby?
- 27. angularjs - przełącznik ng nie wiąże się z modelem ng
- 28. Czy istnieje formant TimePicker w WPF (.NET 4)?
- 29. WPF - powiązanie z właściwością niestandardowego obiektu znajdującego się wewnątrz innego obiektu
- 30. Znajdź element, który zamknął modalne
Wydajność kodu jest świetna! –