在VS2022的 XAML IntelliSense中,对于自定义的WPF依赖属性,TypeConverter.GetStandardValues未被调用

编程语言 2026-07-09

TypeConverter.GetStandardValues未被VS2022的 XAML IntelliSense调用,用于自定义WPF依赖属性

我有一个包含两个项目的WPF解决方案:

  • MyLibrary — WPF类库,包含自定义控件和TypeConverter
  • MyApp — 参考MyLibrary的 WPF应用,在其中编写XAML

我希望在XAML编辑器(MyApp中)按Ctrl+Space时,能弹出一个自定义DependencyProperty的候选值下拉列表。我实现了一个 TypeConverter,配合 GetStandardValues,但并未出现任何完成列表。

MyLibrary代码

[TypeConverter(typeof(FieldNameConverter))]
public class FieldName
{
    public string Value { get; set; } = string.Empty;
    public FieldName() { }
    public FieldName(string value) => Value = value;
    public override string ToString() => Value;
}

public class FieldNameConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        => sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        => value is string s ? new FieldName(s) : base.ConvertFrom(context, culture, value);

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => false;

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        => new StandardValuesCollection(new[] { "AAA", "BBB", "CCC" });
}

public class PropertyAxisBar : Control
{
    public static readonly DependencyProperty FieldNameProperty =
        DependencyProperty.Register(
            nameof(FieldName),
            typeof(FieldName),
            typeof(PropertyAxisBar),
            new PropertyMetadata(new FieldName()));

    // Variant 1: TypeConverter on the property
    [TypeConverter(typeof(FieldNameConverter))]
    public FieldName FieldName
    {
        get => (FieldName)GetValue(FieldNameProperty);
        set => SetValue(FieldNameProperty, value);
    }
}

我还测试了 Variant 2[TypeConverter] 应用于类本身(如上所示),但属性上没有该属性标记。两种变体都不起作用。

MyApp XAML

<local:PropertyAxisBar FieldName="|" />
<!-- Ctrl+Space here — nothing appears -->

我已验证的内容

  • Brush 属性在同一控件上确实会显示完成列表(SystemBrushes)——因此IntelliSense总体上是可用的
  • 在XAML编辑器中按Ctrl+Space时,GetStandardValues 的断点从未命中
  • [TypeConverter] 属性位于 FieldName 类上
  • VS2022、.NET 6 / .NET 4.8、WPF

问题

VS2022的 XAML编辑器是否会对自定义类型调用 TypeConverter.GetStandardValues? 如果不会——在XAML编辑器中为DependencyProperty值提供自定义完成列表的正确方式是什么? 是否只有使用单独的 .Design 程序集并包含 IProvideAttributeTable 的方案才是可选项?

解决方案

对普通XAML属性值的建议仅在XAML编辑器能够静态理解的情况下才可用:基本字面值、布尔值、枚举、已知的WPF/XAML值类型、资源、绑定、元素名称、标记扩展等。其中有些在设计时实际上是内置支持,而不是通过分析器动态发现。

IntelliSense通常不会实例化任意自定义 TypeConverter 并调用 GetStandardValues() 来发现可能的值。TypeConverter 主要在XAML处理器将普通字符串属性值解析为目标CLR类型时使用。它并非用于设计时。

一个实际可行的选项是在有效集合有限时将属性类型设为枚举。枚举值便于IntelliSense进行检查,因此编辑器可以针对简单属性语法提示定义的枚举成员。

对于非枚举的自定义值对象,IntelliSense通常无法知道哪些字符串是有效的,因为这类知识存放在自定义转换器逻辑中。解析属性类型的唯一路径是通过 TypeConverter。但转换器是在构建时被调用的(有时也会在设计器渲染UI时在设计器预览窗格中被调用)。

使用 {x:Static ...} 也可以获得更好的完成,因为此时值以类型/成员引用的形式表达,而不是神秘字符串。标记扩展路径绕过目标属性的常规字符串到类型的转换:扩展直接提供值。

因此,结论是如果你关心IntelliSense的支持且该类型允许,应该尝试将属性类型设为枚举。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章