【问题标题】:Can TypeConverters from WinForms be used in WPF?WinForms 中的 TypeConverters 可以在 WPF 中使用吗?
【发布时间】:2020-10-15 14:07:02
【问题描述】:

C#,WPF。在 WPF 应用程序中,我有最初来自 WinForms 的类,这些类具有 TypeConverters 和相应的装饰器。从我在网上可以找到的信息来看,TypeConverter 似乎没有得到普遍支持,并且往往主要用于 Winforms。但我一直无法在 WPF 中找到关于其范围/适用性的清晰简单的解释。

我创建了以下最小示例。 LatitudeLongitudedoubles,我希望它们出现在 xceed PropertyGrid 中,格式为(现有)strings strings。在最简单的情况下,这种格式会添加一个度数符号,但也可以在不同的测量单位之间进行转换。

这里TypeConverter 显然没有被使用。我在PropertyGrid 中看到“1”和“2”,在Textbox 中看到“1”。

应该以这种方式工作,还是我需要以更以 WPF 为中心的方式重写(例如ValueConverter:IValueConverter)?

<Window x:Class="PropertyGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PropertyGridTest"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Orientation="Vertical">
            <xctk:PropertyGrid Name="propertyGrid"/>
            <TextBox Name="textBox" Text="{Binding Path=Latitude}"/>
        </StackPanel>
    </Grid>
</Window>

namespace PropertyGridTest
{

    public class Foo {
        [TypeConverter(typeof(DegreesTypeConverter))]
        public double Latitude { get; set; } = 1.0;
        [TypeConverter(typeof(DegreesTypeConverter))]
        public double Longitude { get; set; } = 2.0;
    }

    public partial class MainWindow : Window
    {
        Foo bar = new Foo();
        public  MainWindow()
        {
            InitializeComponent();
            propertyGrid.AutoGenerateProperties = true;
            propertyGrid.SelectedObject = bar;
            textBox.DataContext = bar;
        }
    }

    public class DegreesTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(string);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            return (value is string) ? 999.0 : 0.0;
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            return (destinationType == typeof(string)) ? "[formatted string]" : "";
        }
    }

}

【问题讨论】:

  • TypeConverters 当然可以在 WPF 中使用。它们不是特定于 WinForms 的概念。但是,您需要将 TypeConverterAttribute 应用于 Binding 的目标属性,而不是其源(就像您所做的那样)。由于您正在绑定 TextBox 的 Text 属性,这显然是不可能的。改用绑定转换器:docs.microsoft.com/en-us/dotnet/desktop/wpf/data/…
  • 不确定 WPF 在多大程度上尊重这些属性。可以肯定的是,我会编写正确的IValueConverter,其内部实现只是简单地委托给现有的TypeConverter

标签: c# wpf typeconverter


【解决方案1】:

应该以这种方式工作,还是我需要以更以 WPF 为中心的方式重写(例如 ValueConverter:IValueConverter)?

是的,WPF 使用值转换器将源属性的值从一种类型转换为另一种类型。如果您不指定一个,它将使用一个内置转换器,该转换器基本上只是在值上调用ToString()。框架不会检查数据绑定的属性是否用 [TypeConverter] 属性修饰。

然而,TypeConverters 用于将 XAML 字符串转换为其他类型。请参阅docs 了解更多信息。

【讨论】:

  • 谢谢 - 有道理。那么我如何将值转换器应用于 xceed 属性网格?我没有指定单独的绑定。我只设置了 SelectedObject 属性,其余的由控件完成。
  • PropertyGrid 支持DataTemplate 进行格式化。所以也许我需要一个DataTemplate 中的ValueConverter,针对它适用的特定属性?
  • @wotnot:使用EditorTemplate
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多