Как вы в WPF привязываетесь к методу объектов в этом сценарии?
public class RootObject
{
public string Name { get; }
public ObservableCollection<ChildObject> GetChildren() {...}
}
public class ChildObject
{
public string Name { get; }
}
XAML:
<TreeView ItemsSource="some list of RootObjects">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type data:RootObject}"
ItemsSource="???">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type data:ChildObject}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Здесь я хочу привязать GetChildren
метод к каждому RootObject
дереву.
РЕДАКТИРОВАТЬ Привязка к ObjectDataProvider
объекту, похоже, не работает, потому что я привязываюсь к списку элементов, и ObjectDataProvider
требуется либо статический метод, либо он создает собственный экземпляр и использует его.
Например, используя ответ Мэтта, я получаю:
System.Windows.Data Ошибка: 33: ObjectDataProvider не может создать объект; Тип = 'RootObject'; Ошибка = 'Неверные параметры для конструктора.'
System.Windows.Data Ошибка: 34: ObjectDataProvider: сбой при попытке вызвать метод для типа; Метод = 'GetChildren'; Тип = 'RootObject'; Error = 'Указанный член не может быть вызван на цели.' TargetException: 'System.Reflection.TargetException: нестатический метод требует цели.
источник
Ответы:
Другой подход, который может сработать для вас, - создать кастом,
IValueConverter
который принимает имя метода в качестве параметра, чтобы его можно было использовать следующим образом:Этот преобразователь найдет и вызовет метод, используя отражение. Для этого у метода не должно быть аргументов.
Вот пример источника такого преобразователя:
public sealed class MethodToValueConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var methodName = parameter as string; if (value==null || methodName==null) return value; var methodInfo = value.GetType().GetMethod(methodName, new Type[0]); if (methodInfo==null) return value; return methodInfo.Invoke(value, new object[0]); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException("MethodToValueConverter can only be used for one way conversion."); } }
И соответствующий модульный тест:
[Test] public void Convert() { var converter = new MethodToValueConverter(); Assert.AreEqual("1234", converter.Convert(1234, typeof(string), "ToString", null)); Assert.AreEqual("ABCD", converter.Convert(" ABCD ", typeof(string), "Trim", null)); Assert.IsNull(converter.Convert(null, typeof(string), "ToString", null)); Assert.AreEqual("Pineapple", converter.Convert("Pineapple", typeof(string), "InvalidMethodName", null)); }
Обратите внимание, что этот преобразователь не применяет
targetType
параметр.источник
Не уверен, насколько хорошо это будет работать в вашем сценарии, но вы можете использовать
MethodName
свойство,ObjectDataProvider
чтобы он вызывал определенный метод (с определенными параметрами вашегоMethodParameters
свойства) для получения его данных.Вот фрагмент, взятый прямо со страницы MSDN:
<Window.Resources> <ObjectDataProvider ObjectType="{x:Type local:TemperatureScale}" MethodName="ConvertTemp" x:Key="convertTemp"> <ObjectDataProvider.MethodParameters> <system:Double>0</system:Double> <local:TempType>Celsius</local:TempType> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </Window.Resources>
Итак, это
ObjectDataProvider
вызываетConvertTemp
метод экземпляраTemperatureScale
класса, передавая два параметра (0
иTempType.Celsius
).источник
К методу привязать надо?
Можете ли вы привязать свойство к методу, получателем которого является метод?
public ObservableCollection<ChildObject> Children { get { return GetChildren(); } }
источник
Если вы не можете добавить свойство для вызова метода (или создать класс-оболочку, который добавляет это свойство), единственный известный мне способ - это использовать ValueConverter.
источник
ObjectDataProvider также имеет свойство ObjectInstance, которое можно использовать вместо ObjectType.
источник
Вы можете использовать
System.ComponentModel
для динамического определения свойств типа (они не являются частью скомпилированных метаданных). Я использовал этот подход в WPF, чтобы включить привязку к типу, который хранит свои значения в полях, поскольку привязка к полям невозможна.Эти
ICustomTypeDescriptor
иTypeDescriptionProvider
типы могут позволить вам достичь того, чего вы хотите. Согласно этой статье :Я сам не пробовал этот подход, но надеюсь, что он поможет в вашем случае.
источник
Чтобы привязаться к методу объекта в сценарии WPF, вы можете привязаться к свойству, которое возвращает делегат.
источник