是否存在在 XAML 中使用任意 C# 表达式的现有方法?
我希望能够在 XAML 中使用任意 C# 表达式。通常,这是根据两个绑定值计算 UI 元素的属性。
例如,根据其他两个属性计算 UI 元素的宽度。
这是我希望 XAML 看起来像这样的人为示例:
<TextBox
x:Name="textBox1"
/>
<TextBox
x:Name="textBox2"
/>
<Rectangle
Height={Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text)}
/>
当然,XAML 中没有内置的方法可以执行此操作。
我知道我可以将 MultiBinding 与自定义转换器结合使用,这通常是我做这种事情的方式。然而,在我看来,在 XAML 中包含一些 C# 代码会简单得多,我想知道是否有人已经使用 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 XAML.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以像这样将 C# 代码嵌入到 XAML 中:
但根本不推荐这种方法,因为它将纯表示层与业务逻辑混合在一起。
You embed C# code into XAML like this:
But this approach is not recommended at all because it mixes the pure presentation layer with business logic.
我见过采用 IronPython 代码并调用 DLR 的自定义 Xaml 转换器。它不完全是 C#,但它肯定没有使用 [CDATA] 标签的方法难看。
http://pybinding.codeplex.com/
这是有关此问题的开源项目的链接。
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.
将您的表达式包装到公共属性中并绑定到该属性。
在 C# 代码隐藏中:
在 XAML 中:
Wrap your expression into a public property and bind to that property.
In C# codebehind:
In XAML:
请注意,使用这样的代码,
一旦某些操作数发生更改,就很难重新计算值(尽管并非完全不可能,但要牢记 Linq 表达式)。当源更改时目标值的自动更新是 WPF 绑定的主要优点之一。
Please mind that with the code like
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.
我的问题现在有了答案。这不是我最初寻找的答案,而且有点啰嗦,但它确实有效。
我正在读乔什·史密斯的这篇文章。他建议不要使用值转换器,而是将计算推入视图模型并将其作为属性公开:
http://groups.google.com/group/wpf-disciples/browse_thread/thread/3fe270cd107f184f?pli=1
在我的例子中,“textBox1”的文本和 'textBox2' 应该绑定到视图模型中,因此当它们在视图模型中发生更改时,我知道是时候进行计算并更新依赖属性了。然后,依赖属性会触发其属性更改事件,并且 UI 会根据该事件进行更新。
如果您想让表达式依赖于只读控件属性,而无法轻松绑定到视图模型,则可以遵循此处提供的建议:
将只读 GUI 属性推回 ViewModel
我仍然希望能够嵌入(非-业务逻辑)XAML 中的表达式。但鉴于这不是内置的,任何执行此操作的方法都可能有点麻烦。遍历视图模型似乎是执行此操作的正确方法,但也许有一天我会尝试编写一个允许在 XAML 中表达的标记扩展。
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.