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
항목 목록에 바인딩하기 때문에 EDIT Binding이 작동하지 않는 것 같습니다 ObjectDataProvider
. 정적 메서드 가 필요하거나 자체 인스턴스를 만들고 사용합니다.
예를 들어 Matt의 대답을 사용하면 다음과 같은 결과를 얻습니다.
System.Windows.Data 오류 : 33 : ObjectDataProvider가 개체를 만들 수 없습니다. Type = ‘RootObject’; Error = ‘잘못된 생성자 매개 변수.’
System.Windows.Data 오류 : 34 : ObjectDataProvider : 형식에서 메서드를 호출하는 데 실패했습니다. Method = ‘GetChildren’; Type = ‘RootObject’; 오류 = ‘지정된 구성원은 대상에서 호출 할 수 없습니다.’ TargetException : ‘System.Reflection.TargetException : 비 정적 메서드에는 대상이 필요합니다.
답변
작동 할 수있는 또 다른 접근 방식 IValueConverter
은 메서드 이름을 매개 변수 로 사용하는 사용자 지정을 만들어 다음 과 같이 사용하는 것입니다.
ItemsSource="{Binding
Converter={StaticResource MethodToValueConverter},
ConverterParameter='GetChildren'}"
이 변환기는 리플렉션을 사용하여 메서드를 찾고 호출합니다. 메서드에 인수가 없어야합니다.
다음은 이러한 변환기 소스의 예입니다.
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
).
답변
메서드에 바인딩해야합니까?
getter가 메소드 인 속성에 바인딩 할 수 있습니까?
public ObservableCollection<ChildObject> Children
{
get
{
return GetChildren();
}
}
답변
메서드를 호출하는 속성을 추가하거나 해당 속성을 추가하는 래퍼 클래스를 만들 수 없다면 내가 아는 유일한 방법은 ValueConverter를 사용하는 것입니다.
답변
ObjectDataProvider에는 ObjectType 대신 사용할 수있는 ObjectInstance 속성도 있습니다.
답변
당신이 사용할 수있는 System.ComponentModel
하여 유형의 속성을 동적으로 정의 (컴파일 된 메타 데이터의 일부가 아님). 필드에 바인딩 할 수 없기 때문에 필드에 값을 저장 한 형식에 바인딩 할 수 있도록 WPF에서이 방법을 사용했습니다.
ICustomTypeDescriptor
및 TypeDescriptionProvider
유형은 당신이 원하는 것을 달성 할 수 있습니다. 이 기사 에 따르면 :
TypeDescriptionProvider
구현하는 별도의 클래스를 작성한ICustomTypeDescriptor
다음이 클래스를 다른 유형에 대한 설명 제공자로 등록 할 수 있습니다.
이 접근 방식을 직접 시도한 적은 없지만 귀하의 경우에 도움이 되었기를 바랍니다.
답변
WPF 시나리오에서 개체의 메서드에 바인딩하려면 대리자를 반환하는 속성에 바인딩 할 수 있습니다.
