2012-02-29 11 views
14

Недавно я обнаружил, что WPF поддерживает различные единицы измерения в XAML. Помимо DIP-модулей по умолчанию, есть также поддержка пикселей, дюймов и сантиметров (насколько я знаю). Это позволяет дизайнеру написать XAML, например:WPF Units и Code-Behind

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

Однако вы не можете привязать эти значения. Представьте, что у нас есть свойство ViewModel с свойством Dimension, которое является строкой, например «7 см». Следующие действия не будут работать:

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

Ошибка форматаException. Кроме того, при создании в код-позади FrameworkElement, как это:

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

компиляция терпит неудачу, потому что исключение в конструкторе/везде, где вы пытаетесь создать элемент управления.

Интересно:

  • Можно ли использовать натуральные единицы (в моем случае метрики - сантиметров) в код-позади?
  • Как?
  • Полный список единиц поддержки WPF/XAML?

EDIT:

Вот ссылка из комментария ниже, который решает этот вопрос:

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

Это то, что я искал, спасибо! –

+0

Добро пожаловать, рад помочь :) –

2

Для 1) и 2) Поскольку наклоны устройства независимы, вы можете вычислить любую «естественную единицу» и без проблем. Исключение составляют (неестественные :) пиксели, зависящие от устройства.

Создайте ValueConverter, который преобразует значения строк в парные разряды, где ваши нужные единицы могут быть указаны в строке. Затем вы можете использовать ValueConverter в своем Binding и вычислить в ViewModel в «естественных единицах».

Для 3) и реализация: я быстро нашел googled и ничего не нашел, но, возможно, будет более глубокий поиск. В противном случае создание собственного конвертера не должно быть очень сложным. Вот некоторые преобразования: информация о

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

Конвертер I tought может стать для вас способом. Но прежде чем я напишу свой собственный, вы думаете, что есть способ определить, что конвертер использует анализатор XAML? Я думаю, что в WPF должен быть встроенный конвертер, поскольку XAML поддерживает эти устройства. Поэтому я предпочел бы использовать встроенный, я просто не могу определить способ определения, какой он есть. Вероятно, существует некоторое исследование трассировки стека? Я действительно не знаю, какие-нибудь идеи, пожалуйста? :) –

+1

@Aaron: Мне также нравится использовать существующие элементы, однако для каждого конвертера я спросил Google, я быстро нашел имя класса. Но в этом конкретном случае google нечего было сказать. Для обнаружения используемого конвертера в wpf я не могу помочь. Я никогда не углублялся в FCL. Возможно, это стоит специальный вопрос: как отслеживать, какой ValueConverter используется WPF для конкретного преобразования? – HCL

+0

Спасибо за ваш ответ. Я постараюсь составить правильный конвертер самостоятельно и, возможно, задать новый вопрос, если я потерплю неудачу. Еще раз спасибо! –