[DeepSeek] 。。。(一开始的东拉西扯,见:https://www.n.cn/share/r1/9b60484a2a354233a1970b9f554584ab?from=web)
[DLGCY] 你说的好像不对吧,实际上这样写就能赋值 Auto:
[TypeConverter(typeof(LengthConverter))]
public static double GetContentWidth(DependencyObject obj)
{
return (double)obj.GetValue(ContentWidthProperty);
}
[DeepSeek] 根据您的代码示例和 WPF 的底层机制,以下是针对附加属性中 [TypeConverter]
特性的正确应用方式及原理分析:
您提供的代码完全正确且有效,此写法能支持 Auto
赋值的原因:
[TypeConverter]
直接标注在 附加属性的 Get 方法 上,这是 WPF 识别类型转换器的关键位置。Get
方法上的 TypeConverter
特性。应用场景 | 标注位置 | 是否有效 | 示例 |
---|---|---|---|
附加属性 Get 方法 | public static double GetXxx() | ✅ 有效 | 您的代码 |
附加属性定义类 | 类声明上方 | ❌ 无效 | [TypeConverter(...)] class MyAttached |
依赖属性字段 | public static DependencyProperty | ❌ 无效 | [TypeConverter(...)] static DependencyProperty |
只有标注在 附加属性的 Get 方法 上才能被 XAML 解析器识别。
虽然 LengthConverter
主要用于数值转换,但它内置了对以下特殊值的处理:
// 支持的赋值示例
SetContentWidth(element, Double.NaN); // 对应 "Auto"
SetContentWidth(element, 100.0); // 对应 "100" 或 "100px"
Double.NaN
WPF 布局系统将 Double.NaN
解释为自动尺寸(与原生 Width="Auto"
行为一致)。"100px"
、"50%"
等带单位字符串(通过 LengthConverter.ConvertFromString()
)。public class CustomAttached
{
// 1. 注册附加属性
public static readonly DependencyProperty ContentWidthProperty =
DependencyProperty.RegisterAttached(
"ContentWidth",
typeof(double),
typeof(CustomAttached),
new FrameworkPropertyMetadata(
Double.NaN, // 默认值设为 NaN 以支持 Auto
FrameworkPropertyMetadataOptions.AffectsMeasure
)
);
// 2. 在 Get 方法上标注 TypeConverter
[TypeConverter(typeof(LengthConverter))]
public static double GetContentWidth(DependencyObject obj)
{
return (double)obj.GetValue(ContentWidthProperty);
}
// 3. Set 方法无需标注
public static void SetContentWidth(DependencyObject obj, double value)
{
obj.SetValue(ContentWidthProperty, value);
}
}
<Button local:CustomAttached.ContentWidth="Auto" /> <!-- 等价于 Double.NaN -->
<TextBlock local:CustomAttached.ContentWidth="200px" />
<Grid local:CustomAttached.ContentWidth="30%" />
原生依赖属性(如 FrameworkElement.Height
)的写法:
[TypeConverter(typeof (LengthConverter))]
public double Height
{
get => (double) this.GetValue(FrameworkElement.HeightProperty);
set => this.SetValue(FrameworkElement.HeightProperty, (object) value);
}
这是因为:
Get
方法上作为入口点。// ❌ 错误:标注在 Set 方法(完全无效)
public static void SetCustomWidth(DependencyObject obj, double value)
=> obj.SetValue(CustomWidthProperty, value);
// ❌ 错误:标注在依赖属性字段(编译通过但无效)
[TypeConverter(typeof(LengthConverter))]
public static readonly DependencyProperty CustomWidthProperty = ...;
[TypeConverter]
必须标注在 Get 方法上。"Auto"
(转换为 Double.NaN
)、带单位数值(px
, %
等)。GridLength
,double
+ NaN
即可实现 Auto
语义。