English 中文(简体)
如何创建静态可约束性财产说明对象
原标题:How to create static bindable property description object

为确保WPF中的约束性是针对现有财产的,我使用静态财产-名称-财产。

现在我想把更多关于我属性的信息 封装在一个静态属性描述对象、名称、类型、ID等, 但不必为名称设置一个路径可附加的属性, 并且用所有其他信息来设置一个属性 。

问题在于,WPF抱怨财产类型错误,不是字符串,而是财产Info。

我试图绕过这个限制。 例如,我试图使我的财产Info 隐含到字符串, 凌驾于String 之上, 并且从财产Info 到字符串和从财产Info 的字符串都添加一个类型反转器。 没有效果 。

我也不能直接和名字财产连结

<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;
    }
}

有什么建议吗?

最佳回答

您的属性Info 需要有一个 TypeConvertier 将 PropertyPath 转换为系统。 Windows. PropertyPath, 而不是字符串。 另外, 您可能想为此重新使用. NETs System. reflection. PropertyInfo 。

我之前见过这个方法, 其主要原因就是避免在更改属性通知中出现“ 磁字符串 ” 。 所以您也可以看看如何利用系统获得“ 属性Info ” 。 Linq. 这样的表达方式 :

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; }
}

<强度 > EDIT:新答复

是的, 您是对的。 即使您定义了将属性 Info 转换为系统, 也不会有效 。 Windows. PropertyPath 。 我认为这是因为转换器 Type 属性应该放在系统. Windows. propertyPath 类上。 但是, 由于它是一个您并不拥有的类, 您无法在它上设置属性 。 使用 type Descriptionor 添加属性将会有效, 因为 XAML 不使用 TypeDescripor 基础设施 。

您可以通过 MarkupExtension 完成您的转换。 这是完整的代码( 它使用系统. reflection namespace 的属性Info ) :

<强度 > 反射帮助者.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;
        }
    }
}

<强度 > 测试.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; }
    }
}

<强度 > PropertyInfoPapthExtension.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);
        }
    }
}

< pronger > 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>
问题回答

你的语法正确吗?

不久前我不得不跟一个静态的班级绑在一起。对静态绑在一起的语法是不同的。我在这里记录下来的。

< a href=>"http://www.wpfsharp.com/2011/09/04/wpf- contact-to- a- property-of- a-statistic-类/" rel=“nofollow”>WPF 绑定到静态类的属性

但基本上语法是这样的:

{x:Static s:MyStaticClass.StaticValue1}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签