Существует ли способ использовать произвольные выражения C # в XAML? - PullRequest
8 голосов
/ 03 декабря 2010

Я хотел бы иметь возможность использовать произвольные выражения C # в XAML. Обычно это делается для вычисления свойства элемента пользовательского интерфейса на основе двух связанных значений.

Например, вычисление ширины элемента пользовательского интерфейса на основе двух других свойств.

Это надуманный пример того, как бы я хотел, чтобы XAML выглядел так:

<TextBox
   x:Name="textBox1"
   />

<TextBox
   x:Name="textBox2"
   />

<Rectangle
    Height={Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text)}
    />

Конечно, в XAML нет встроенного способа сделать это.

Я знаю, что я мог бы использовать MultiBinding в сочетании с пользовательским конвертером, и я обычно так поступаю. Однако мне кажется, что было бы намного проще просто включить некоторый код C # в XAML, и мне было интересно, решил ли кто-нибудь там эту проблему с расширением XAML или чем-то еще.

Ответы [ 5 ]

2 голосов
/ 03 декабря 2010

Я видел пользовательские конвертеры Xaml, которые принимают код IronPython и вызывают DLR.Это не совсем C #, но, безусловно, он менее уродлив, чем подход с использованием тегов [CDATA].

http://pybinding.codeplex.com/

Это ссылка на проект с открытым исходным кодом по этому вопросу.

2 голосов
/ 03 декабря 2010

Вы встраиваете код C # в XAML следующим образом:

 <x:Code>
            <![CDATA[

            void ButtonOnClick(object sender, RoutedEventArgs args)
            {
                Button btn = sender as Button;
                MessageBox.Show("The button labeled '" +
                                btn.Content +
                                "' has been clicked.","Information Message");
            }
            ]]>
  </x:Code>

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

1 голос
/ 03 декабря 2010

Оберните ваше выражение в публичную собственность и привяжите к этому свойству.

В коде C #:

public double Heigth
{
  get { return Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text); }
}

В XAML:

<Rectangle Height={Binding Heigth} />
1 голос
/ 03 декабря 2010

Обратите внимание, что с кодом типа

Height={Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text)}

особенно трудно (хотя и не совсем невозможно, учитывая выражения Linq) переоценить значение, как только некоторые из операндов изменятся. Автоматическое обновление целевого значения при изменении источника является одним из основных преимуществ привязок WPF.

0 голосов
/ 14 декабря 2010

У меня есть ответ на мой вопрос сейчас.Это не тот ответ, который я искал изначально, и он немного затянут, но он работает.

Я читал этот пост Джош Смит.Он рекомендует не использовать преобразователи значений, а помещать вычисления в модель представления и выставлять их как свойство:

http://groups.google.com/group/wpf-disciples/browse_thread/thread/3fe270cd107f184f?pli=1

В моем случае текст для textBox1 иtextBox2 'должен быть связан с моделью представления, поэтому, когда они изменяются в модели представления, я знаю, что пора выполнять вычисления и обновлять зависимое свойство.Затем зависимое свойство запускает событие своего свойства изменено, и пользовательский интерфейс обновляется из этого.

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

Перенос свойств графического интерфейса только для чтения обратно в ViewModel

Я все еще хотел бы иметь возможность встраивать(не бизнес-логика) выражения в XAML.Но, учитывая, что это не является встроенным способом, это может быть чем-то вроде взлома.Кажется, что правильный просмотр этой модели - это правильный путь, но, возможно, однажды я поэкспериментирую с написанием расширения разметки, которое позволяет выражать в XAML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...