开发者

Is there an existing way to use arbitrary C# expressions in XAML?

I'd like to be able to use arbitrary C# expressions in XAML. Usually this would be to compute a property for a UI element based on two bound values.

For example calculating the width of a UI element based on two other properties.

This is a contrived example of what I'd like the XAML to look like:

<TextBox
   x:Name="textBox1"
   />

<TextBox
   x:Name="textBox2"
   />

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

Of course there is no built-in way of doing this in XAM开发者_开发技巧L.

I know that I could use a MultiBinding combined with a custom converter and this is usually the way I do this kind of thing. However it seems to me that it would be so much simpler to just include some C# code in the XAML and I was wondering if anyone out there had already solved this problem with a XAML extension or something else.


You embed C# code into XAML like this:

 <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>

But this approach is not recommended at all because it mixes the pure presentation layer with business logic.


I've seen custom Xaml converters that take IronPython code and Invoke the DLR. It's not quite C#, but its certainly is less ugly than the approach of using [CDATA] tags.

http://pybinding.codeplex.com/

This is the link to an open source project on the matter.


Wrap your expression into a public property and bind to that property.

In C# codebehind:

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

In XAML:

<Rectangle Height={Binding Heigth} />


Please mind that with the code like

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

it's particularly hard (although not completely impossible, keeping Linq Expressions in mind) to get the value reevaluated as soon as some of the operands change. The automatic update of the target value when the source changes is one of the major advantages of WPF bindings.


I have an answer to my question now. It isn't the answer I was originally looking for, and it is a bit long winded but it does work.

I was reading this post by Josh Smith. He recommends not using value converters but pushing the calculations down into the view-model and exposing it as a property:

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

In my case the text for both 'textBox1' and 'textBox2' should be bound into the view-model, so when they change in the view-model I know its time to do the calculation and update the dependent property. The dependent property then fires its property changed event and the UI updates from that.

If you have a case where you want to make the expression depend on read-only control properties, that you can't easily bind to the view-model, you can follow the advice presented here:

Pushing read-only GUI properties back into ViewModel

I still would like to have the ability to embed (non-business logic) expressions in the XAML. But seeing as this is not built-in any way of doing it is likely to be a bit of a hack. Going through the view-model seems to be the correct way of doing this, but maybe one-day I'll experiment with writing a markup extension that allows expression in XAML.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜