2012-02-29 55 views
14

最近我发现WPF在XAML中支持不同的度量单位。除了默认的DIP,还支持像素,英寸和厘米(据我所知)。这允许设计者编写如下的XAML:WPF单元和代码隐藏

<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

回答

13

您可以在代码中做到这一点的背后通过采用XAML解析器使用相同的转换,则不需要重新实现这个逻辑,如果你不介意身边掠过字符串:

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

的XAML解析器使用TypeConverters将字符串转换为所需要的值,在documentation page of the Width property你可以看到它有一个TypeConverterAttribute指定一个LengthConverter应该被使用。这个属性可以用来本地覆盖应该如何处理一个属性,但是它也可以在类级应用,所以如果一个Employee类有这个属性指定应该使用EmployeeConverter,那么所述转换器将是类型属性的默认值Employee

我有点惊讶绑定不应用此类型转换器,但使用它的IValueConverter里面也非常简单,其实你可以创建一个markup extension从一个类型转换器构造一个IValueConverter,使其很好地通用。

+0

这就是我一直在寻找的,谢谢! – 2012-03-01 00:52:27

+0

不客气,很高兴帮助:) – 2012-03-01 00:53:47

2

对于1)和2)由于DIP封装是设备无关的,可以计算任何“自然单位”来回没有问题。例外是(非自然:)设备相关像素。

创建一个ValueConverter,将字符串值转换为双倍字符串,您可以在字符串中指定所需的单位。然后,您可以在Binding中使用ValueConverter,并在ViewModel中以“自然单位”进行计算。对于3)和执行:我已经快速搜索并没有发现任何东西,但也许会进行更深入的搜索显示的东西。否则,创建你自己的转换器应该不是很困难。这里是一些转换的相关信息:

96DIP == 1inch == 2.54cm; 
1cm == 37.8DIP; 
1zoll == 1inch == 2.54cm; 
+0

我付出转换器可能是一种方式去。但是在我编写我自己的之前,你认为有一种方法可以确定Converter XAML分析器使用的是什么?我认为WPF中必须有一个内置的转换器,因为XAML支持这个单元。所以我会主张使用内置的,我只是无法确定一个确定它是哪一个的方法。可能有些堆栈跟踪调查?我真的不知道,有什么想法吗? :) – 2012-02-29 18:51:17

+1

@Aaron:我也喜欢使用现有的元素,但是对于我询问的每个转换器,我很快找到了类名。但在这个特定的情况下,谷歌没有什么可说的。为了检测wpf中使用的转换器,我忍不住。我从来没有深入了解FCL。也许这值得一个专门的问题:如何跟踪哪些ValueConverter被WPF用于特定的转换? – HCL 2012-02-29 18:56:35

+0

感谢您的回答。我会尝试自己设计一个正确的Converter,如果失败,可能会问一个新问题。再次感谢! – 2012-02-29 18:59:49