WPF单位和代码后台

15

最近我发现WPF在XAML中支持不同的度量单位。除了默认的设备独立像素(DIPs)之外,还支持像素、英寸和厘米(据我所知)。这使得设计师可以编写如下的XAML代码:

<Canvas>
    <Line X1="0cm" X2="3cm" Y1="1cm" Y2="3cm" Stroke="Black"/>
</Canvas>

然而,您无法绑定这些值。假设我们有一个包含 Dimension 属性的 ViewModel,它是一个字符串,例如“7cm”。以下代码将无法正常工作:

<Button Width="{Binding Dimension}">Test</Button>

会抛出 FormatException 异常。同样的,当在代码后台创建一个 FrameworkElement 时,像这样:

Canvas1.Children.Add(new Button() { Width = "3cm", Content = "Test"});

由于在构造函数/您尝试创建控件的任何位置引发了异常,因此编译失败。

我想知道:

  • 是否可以在代码后台中使用自然单位(例如我的情况是公制 - 厘米)?
  • 如何做到?
  • WPF/XAML支持的单位是否有完整列表?

编辑:

以下是下面评论中提供的解决此问题的链接:

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width.aspx

2个回答

17

您可以在代码后端应用与XAML解析器相同的转换,这样做可以避免重新实现此逻辑,如果您不介意传递字符串的话。

button.Width = (double)new LengthConverter().ConvertFrom("2cm");

The XAML解析器使用类型转换器将字符串转换为所需的值,在Width属性的文档页面中,您可以看到它具有指定应使用LengthConverterTypeConverterAttribute。此属性可用于局部覆盖如何处理属性,但也可以应用于类级别,因此,如果一个Employee类具有指定应使用EmployeeConverter的该属性,则该转换器将是Employee类型属性的默认值。
我有点惊讶绑定没有使用这个类型转换器,但在 IValueConverter 中使用它非常简单,事实上,你可以创建一个 markup extension,从类型转换器构造一个 IValueConverter,使其变得更加通用。

2
1)和2)由于DIP是设备无关的,因此可以计算任何“自然单位”而不会出现问题。唯一的例外是(不自然的:) 设备相关像素。
创建一个ValueConverter,将字符串值转换为double,其中您希望在字符串中指定所需的单位。然后,您可以在绑定中使用ValueConverter,并在ViewModel中以“自然单位”进行计算。
对于3)和实施:我快速搜索了一下,但没有找到任何东西,但也许深入搜索会显示出一些东西。否则,创建自己的转换器应该不会很困难。这里有一些转换信息:
96DIP == 1inch == 2.54cm;
1cm == 37.8DIP;
1zoll == 1inch == 2.54cm;

我认为Converter可能是一个可行的方法。但在编写自己的转换器之前,您认为有没有办法确定XAML解析器使用的Converter是什么?我认为WPF中已经有内置的转换器,因为XAML支持这些单位。所以我更愿意使用内置的转换器,只是我无法确定它是哪一个。也许需要进行一些堆栈跟踪调查?我不太清楚,有什么想法吗? :) - Aaron Summernite
1
@Aaron:我也喜欢使用现有的元素,但是对于每个转换器,我问谷歌后很快就找到了类名。但在这种特定情况下,谷歌没有任何信息。关于如何检测WPF中使用的转换器,我无能为力。我从未深入挖掘过FCL。也许这值得一个专门的问题:如何跟踪WPF在特定转换时使用的ValueConverter? - HCL
谢谢您的回答。我会尝试自己找到一个合适的转换器,如果失败的话可能会再次提出一个新的问题。再次感谢! - Aaron Summernite
1
啊哈!http://msdn.microsoft.com/zh-cn/library/system.windows.frameworkelement.width.aspx - Aaron Summernite
1
@HCL:也许你会对我的回答感兴趣。 - H.B.
@H.B. 感谢您的评论和+1,也感谢您的回答(以及评论):很好知道。 - HCL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接