如何创建静态可绑定属性描述对象
Posted
技术标签:
【中文标题】如何创建静态可绑定属性描述对象【英文标题】:How to create static bindable property description object 【发布时间】:2012-06-01 20:13:46 【问题描述】:为了确保 WPF 中的绑定以现有属性为目标,我使用了静态属性名称属性。
现在我不想将有关我的属性的更多信息封装到静态属性描述对象、名称、类型、ID 等中,但不必为名称提供一个可路径绑定的属性,并为所有其他信息提供一个属性。
问题是 WPF 抱怨属性类型错误,不是 String 而是 PropertyInfo。
我正试图以某种方式绕过这个限制。例如,我尝试让我的 PropertyInfo 隐式转换为字符串,覆盖 ToString 并将 PropertyInfo 中的 TypeConverter 添加到字符串和 PropertyInfo 中的字符串。没有任何效果。
我也不能直接绑定到 Name 属性。
<TextBlock Text="Binding Path=x:Static l:Test.TitleProperty" />
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
TypeDescriptor.AddAttributes(typeof(string),
new TypeConverterAttribute(typeof(StringFromPropertyConverter)));
DataContext = new Test Title = "hello" ;
public class Test
public static readonly PropertyInfo TitleProperty =
new PropertyInfo Name = "Title" ;
public string Title get; set;
[TypeConverter(typeof(PropertyToStringConverter))]
public class PropertyInfo
public string Name get; set;
public static implicit operator string(PropertyInfo p) return p.Name;
public override string ToString()
return Name;
public class PropertyToStringConverter : TypeConverter
public override bool CanConvertTo(ITypeDescriptorContext context,
Type destinationType)
if (destinationType == typeof(string)) return true;
return base.CanConvertTo(context, destinationType);
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value,
Type destinationType)
return ((PropertyInfo)value).Name;
public class StringFromPropertyConverter : TypeConverter
public override bool CanConvertFrom(ITypeDescriptorContext context,
Type sourceType)
if (sourceType == typeof(PropertyInfo)) return true;
return base.CanConvertFrom(context, sourceType);
public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value)
return ((PropertyInfo)value).Name;
有什么建议吗?
【问题讨论】:
【参考方案1】:您的 PropertyInfo 需要有一个 TypeConverter 才能将 PropertyInfo 转换为 System.Windows.PropertyPath,而不是字符串。此外,您可能需要考虑为此目的重用 .NETs System.Reflection.PropertyInfo。
我以前见过这种方法,其主要原因是避免在属性更改通知中出现“神奇的字符串”。因此,您还可以看看如何使用 System.Linq.Expressions 来获取 PropertyInfo,如下所示:
public static class ReflectionHelper
public static PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> getter)
return (PropertyInfo)((MemberExpression)getter.Body).Member;
并像这样使用它:
public class Test
public static readonly PropertyInfo TitleProperty = ReflectionHelper.GetPropertyInfo<Test>(x => x.Title);
public string Title get; set;
编辑:新答案
是的,你是对的。即使您定义 TypeConverter 将 PropertyInfo 转换为 System.Windows.PropertyPath,它也不起作用。我认为这是因为 ConverterType 属性应该放在 System.Windows.PropertyPath 类上。但是由于它是一个你不拥有的类,你不能在它上面放置属性。使用 TypeDescriptor 添加属性将不起作用,因为 XAML 不使用 TypeDescriptor 基础结构。
您可以使用 MarkupExtension 完成转换。这是一个完整的代码(它使用来自 System.Reflection 命名空间的 PropertyInfo):
ReflectionHelper.cs
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace WpfApplication
public static class ReflectionHelper
public static PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> getter)
return (PropertyInfo)((MemberExpression)getter.Body).Member;
Test.cs
using System.Reflection;
namespace WpfApplication
public class Test
public static readonly PropertyInfo TitleProperty = ReflectionHelper.GetPropertyInfo<Test>(x => x.Title);
public string Title get; set;
PropertyInfoPathExtension.cs
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;
namespace WpfApplication
public class PropertyInfoPathExtension : MarkupExtension
private readonly PropertyInfo propertyInfo;
public PropertyInfoPathExtension(PropertyInfo propertyInfo)
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
this.propertyInfo = propertyInfo;
public override object ProvideValue(IServiceProvider serviceProvider)
return new PropertyPath(propertyInfo);
MainWindow.xaml
<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Test Title="hello"/>
</Window.DataContext>
<TextBlock Text="Binding Path=local:PropertyInfoPath x:Static local:Test.TitleProperty"/>
</Window>
【讨论】:
我确实尝试用 PropertyPath 替换 String 但它没有帮助:( 我已经编辑了我的答案并为您提供了新的解决方案。看看吧。【参考方案2】:那么,你的语法正确吗?
不久前我不得不绑定到一个静态类。绑定到静态的语法是不同的。我在这里记录了它。
WPF Binding to a property of a static class
但本质上的语法是这样的:
x:Static s:MyStaticClass.StaticValue1
【讨论】:
以上是关于如何创建静态可绑定属性描述对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在核心数据上创建可观察对象并将其绑定到 tableView
如何在 SwiftUI 中使用可观察对象并与 NavigationLink 绑定?
将静态方法/函数绑定到 XAML 中的 Func<T> 属性