2015-11-23 3 views
0

Простейшая вещь, я уверен, но для жизни меня я не могу найти решение для этого. Я определяю двойное значение ширины моего контроля, как так:WPF - использование статического ресурса в выражении

<sys:Double x:Key="dbl_controlPanelWidth">420</sys:Double> 

Теперь я хотел бы задать ширину одного элемента управления на одну треть этой ширины. Есть ли способ сделать это? Что-то вроде:

<Button x:Name="btn_myButton" Width="{StaticResource dbl_controlPanelWidth}/3" 

спасибо.

+0

Вы можете использовать конвертер. Или какой-то макет * magic * (например, создавая сетку с 2 столбцами, где первый столбец '' * "' и содержит элемент, к которому вы привязываете 'ActualWidth', а второй столбец' '2 *" '). – Sinatr

+0

Я думаю, что лучшим решением является использование расширения разметки, взгляните на это http://www.codeproject.com/Articles/305932/Static-and-Type-markup-extensions, именно когда вызовите статические методы, надейтесь, что это work – toumir

ответ

2

Вы может привязать высоту, установив Source свойство BindingExpression.

<Button x:Name="btn_myButton" 
      Width="{Binding Source={StaticResource dbl_controlPanelWidth}, 
          Converter={converters:ScreenRatioConverter}, 
          ConverterParameter='3'}" 

Используя так что вы можете применять любые из статических источников или также ViewModel им свойства.

Вы можете определить ScreenRatioConverter так:

[ValueConversion(typeof(string), typeof(string))] 
    public class ScreenRatioConverter : MarkupExtension, IValueConverter 
    { 
      private static ScreenRatioConverter _instance; 

      public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
      { 

       double size = System.Convert.ToDouble(value)/System.Convert.ToDouble(parameter, CultureInfo.InvariantCulture); 
       return size.ToString("G0", CultureInfo.InvariantCulture); 
      } 

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
      { 
       throw new NotImplementedException(); 
      } 

      public override object ProvideValue(IServiceProvider serviceProvider) 
      { 
       return _instance ?? (_instance = new ScreenRatioConverter()); 
      } 

     } 

Передача ваш фактор значение (3) в качестве параметра дает вам повторно удобство и гибкость, чтобы изменить размер вашего width в любое время.

+0

Извините за ответ с такой задержкой. Боюсь, этого не избежать. Спасибо за ваш ответ. Я знал, что преобразователи ценности могут выполнять то, что мне нужно, но я надеялся, что есть более простой способ. В итоге я создал свой собственный конвертер, который позволяет выполнять основные арифметические операции. Я использовал ваш в качестве отправной точки. Благодаря! – EEALNT

0

Вы можете иметь выражения в привязках.

Что вам нужно сделать, это связать ширину к ресурсу через преобразователь и кода выражение в конвертере:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value is double) 
     { 
      return (double)value/3; 
     } 

     return value; 
    } 

Тогда ваш XAML просто:

<Button x:Name="btn_myButton" Width="{StaticResource dbl_controlPanelWidth}" /> 
+0

XAML должен показать, как объявить конвертер и ссылаться на него в привязке. –

1

Предлагаю вам ознакомиться с этим ответом: Do math in xaml Также эта ссылка является короткой и правой к точке: Arithmetic operations in Xaml.

+1

Действительно. Вторая ссылка, в частности, как вы выразились, «короткая и правильная». Благодаря!Однако в итоге я превратился в более сложный конвертер, позволяющий выполнять все четыре основные арифметические операции (+, -, *, /). – EEALNT

0

Поскольку я не добавляю новую информацию, но отправляю решение, в конце концов я закончил, я отправляю ответ на свой вопрос для других людей. Надеюсь, все в порядке. Не то, что испытали с SO еще.

Итак ... Я начал с кодом Niraj Доши, в расширил его немного, чтобы поддержать основные арифметические операции (+, -, *, /) и в конечном итоге с этим:

/// <summary> 
    /// Converter for simple math operations. It should be bound to a source path, which has a number for its value. 
    /// the parameter should be a string with a format of "N|xxxxx" (without quotes), where N is a number, the '|' 
    /// sign is a separator and the second parameter (xxxxx) is a string defining the operation. Valid values are 
    /// add, subtract, multiply and divide. Below example shows how a button's width is set to one third of the 
    /// parent's canvas width: 
    /// <Canvas x:Name="mainCanvas" Height="220" Width="260"> 
    ///  <Button x:Name="button1" 
    ///    Content="Button" 
    ///    Height="30" 
    ///    Canvas.Left="0" Canvas.Top="79" 
    ///    Width="{Binding ElementName=mainCanvas, Path=Width, 
    ///        Converter={local:ScreenRatioConverter}, 
    ///        ConverterParameter='3|divide'}"/> 
    /// </Canvas> 
    /// </summary> 
    [ValueConversion(typeof(string), typeof(string))] 
    public class ScreenRatioConverter : MarkupExtension, IValueConverter 
    { 
     private static ScreenRatioConverter _instance; 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      string parameterString = parameter as string; 
      string[] parameters = parameterString.Split(new char[] { '|' }); 
      double par1 = System.Convert.ToDouble(value); 
      double par2 = System.Convert.ToDouble(parameters[0], CultureInfo.InvariantCulture); 
      string operation = (string)parameters[1]; 
      double result = 20; //Default value to return if anything goes wrong. 
      if (operation.Equals("add")) 
      { result = par1 + par2; } 
      else if (operation.Equals("subtract")) 
      { result = par1 - par2; } 
      else if (operation.Equals("multiply")) 
      { result = par1 * par2; } 
      else if (operation.Equals("divide")) 
      { result = par1/par2; } 

      return result; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     //Needs to be overridden because of inheritance from MarkupExtension. 
     public override object ProvideValue(IServiceProvider serviceProvider) 
     { 
      return _instance ?? (_instance = new ScreenRatioConverter()); 
     } 

    } 

} 

Любые комментарии по поводу улучшения или сделать код более безопасным/чистым/... приветствуем.

Смежные вопросы