【发布时间】:2018-11-30 14:39:37
【问题描述】:
我正在尝试简化将 WPF 控件绑定到我项目中的属性的过程。我希望能够以类似于以下方式调用该方法:
MyList.Bind( x => x.ItemsSource, App.Globals.ItemManager.Items );
我编写了一个扩展方法,该方法扩展了DependencyObject,并从给定的PropertyInfo(如果存在)正确解析DependencyProperty。现在,我需要从 sourceProperty 解析父对象,以便为正确的属性生成路径。
我的问题是,由于我将sourceProperty作为对象传递,似乎没有办法使用反射来获取父级的实例,也没有办法获取属性的PropertyInfo。我想保持参数列表尽可能干净并尽可能接近上面的示例,但如果没有解决方法,添加参数就可以了。
这是我当前的代码:
public static class BindingExtensions
{
public static void Bind<TControl, TProperty>(
this TControl control,
Expression<Func<TControl, TProperty>> controlPropertyExpression,
object sourceProperty )
where TControl : DependencyObject
{
// Get DependencyProperty of control
var controlPropertyInfo = controlPropertyExpression.GetPropertyInfo();
var controlDependencyProperty = GetDependencyPropertyFromProperty( controlPropertyInfo );
if( controlDependencyProperty == null )
throw new ArgumentException(
$"Could not resolve DependencyProperty for '{controlPropertyInfo.Name}' " +
$"in class {controlPropertyInfo.ReflectedType}." );
// Determine source object and path
// TODO:
// var source = {parent instance of sourceProperty}
// var path = {name of sourceProperty}
// Bind
return;
}
public static IEnumerable<FieldInfo> GetDependencyPropertiesFromType( Type controlType )
{
var properties = controlType
.GetFields( BindingFlags.Static | BindingFlags.Public )
.Where( x => x.FieldType == typeof( DependencyProperty ) );
if( controlType.BaseType != null )
properties = properties.Union( GetDependencyPropertiesFromType( controlType.BaseType ) );
return properties;
}
public static FieldInfo GetDependencyPropertyFromProperty( PropertyInfo propertyInfo, Type controlType = null )
{
if( controlType == null )
controlType = propertyInfo.ReflectedType;
var property = controlType
.GetFields( BindingFlags.Static | BindingFlags.Public )
.FirstOrDefault( x =>
x.FieldType == typeof( DependencyProperty ) &&
((DependencyProperty)x.GetValue( null )).Name == propertyInfo.Name );
if( property == null && controlType.BaseType != null )
return GetDependencyPropertyFromProperty( propertyInfo, controlType.BaseType );
return property;
}
}
【问题讨论】:
-
@Clemens 是的,这是问题的一部分。我可以传入 byref,但我仍然需要一种方法来使用反射来获取所需的信息。
-
除了属性名称之外,您还需要什么来创建绑定路径?只需传递
nameof(App.Globals.ItemManager.Items)和源对象即可。
标签: c# .net wpf data-binding