Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在XAML中是否存在使用任意C#表达式的现有方法?_C#_Wpf_Xaml - Fatal编程技术网

在XAML中是否存在使用任意C#表达式的现有方法?

在XAML中是否存在使用任意C#表达式的现有方法?,c#,wpf,xaml,C#,Wpf,Xaml,我希望能够在XAML中使用任意C#表达式。通常这是基于两个绑定值计算UI元素的属性 例如,根据其他两个属性计算UI元素的宽度 这是一个我希望XAML看起来像的人为示例: <TextBox x:Name="textBox1" /> <TextBox x:Name="textBox2" /> <Rectangle Height={Double.Parse(textBox1.Text) + Double.Parse(textBox2.T

我希望能够在XAML中使用任意C#表达式。通常这是基于两个绑定值计算UI元素的属性

例如,根据其他两个属性计算UI元素的宽度

这是一个我希望XAML看起来像的人为示例:

<TextBox
   x:Name="textBox1"
   />

<TextBox
   x:Name="textBox2"
   />

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

当然,在XAML中没有实现这一点的内置方法

我知道我可以使用一个多绑定和一个自定义转换器,这通常是我做这类事情的方式。然而,在我看来,只在XAML中包含一些C代码要简单得多,我想知道是否有人已经用XAML扩展或其他东西解决了这个问题。

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


但不推荐使用这种方法,因为它将纯表示层与业务逻辑混合在一起。

我见过一些定制的Xaml转换器,它们采用IronPython代码并调用DLR。它不太像C#,但它肯定没有使用[CDATA]标记的方法那么难看


这是一个关于这个问题的开源项目的链接。

请注意,代码如下

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

一旦某些操作数发生更改,就很难重新计算值(尽管并非完全不可能,但要记住Linq表达式)。当源更改时自动更新目标值是WPF绑定的主要优点之一。

将表达式包装到公共属性并绑定到该属性

在C#codebehind中:

public double Heigth
{
  get { return Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text); }
}
<Rectangle Height={Binding Heigth} />
在XAML中:

public double Heigth
{
  get { return Double.Parse(textBox1.Text) + Double.Parse(textBox2.Text); }
}
<Rectangle Height={Binding Heigth} />

我现在对我的问题有了答案。这不是我最初寻找的答案,虽然有点冗长,但确实有效

我正在读乔希·史密斯的这篇文章。他建议不要使用值转换器,而是将计算向下推到视图模型中,并将其作为属性公开:

在我的例子中,“textBox1”和“textBox2”的文本都应该绑定到视图模型中,因此当它们在视图模型中更改时,我知道是时候进行计算并更新依赖属性了。然后,dependent属性触发其属性更改事件,UI将从此事件更新

如果您希望使表达式依赖于只读控件属性,并且无法轻松绑定到视图模型,则可以遵循此处提供的建议:



我仍然希望能够在XAML中嵌入(非业务逻辑)表达式。但鉴于这不是内置的任何方式,这可能有点像黑客。浏览视图模型似乎是实现这一点的正确方法,但也许有一天我会尝试编写一个允许使用XAML表达的标记扩展。

谢谢你的回答,但这并不是我真正想要的。我想使用C#主要是为了方便地设置UI元素的属性,以避免创建自己的转换器和使用多重绑定。为什么要避免使用转换器和多重绑定?它们就是方便。创建一个新类比键入一个表达式更方便的方法是什么?这个类可以独立运行tested@Ashley戴维斯:维修。让自己站在一个可怜的家伙的立场上,他将不得不在五年后维护这个应用程序:一切都是可执行的,一切都有状态,一切都取决于其他一切。“但是,嘿,写这篇文章的人说它很方便!”换句话说,花在应用程序上的时间只有20%用于编码,剩下的80%用于维护。听起来很有趣。知道在哪里可以找到这些转换器吗?谢谢链接。这看起来非常接近我想要的。你也可以尝试调整这种方法,将Mono的编译器作为一种服务使用。当然,我不知道要做多少工作。谁来维护你的工作都有问题。如果XAML编译器真的支持这一点,那么维护这些XAML文件就容易多了!这是因为您不必创建大量的转换器类来完成工作,而且更少的类意味着更少的维护。是的,可能是这样,但这违背了将表示与业务逻辑分离的目标,这意味着更多的维护。而且,由于使用不规范,会造成混乱。但可能表达式不是业务逻辑?此外,有时ui和业务逻辑的分离很好,这正是您想要的。有时候,你想快速完成一个一次性原型,而你根本不在乎这种分离。我并不是想假装那是有效的XAML!理论上,重新计算表达式应该不会太难。如果XAML编译器能够实际处理该表达式,它将知道“textBox1.Text”和“textBox2.Text”是依赖属性,因此它将知道当它们更改时,必须重新计算该表达式。@Ashley:我也没有。记住这一点,实现上述功能的唯一方法是使用标记扩展。上述扩展可能非常复杂,足以构建linq表达式、检查所有操作数类型并构建适当的多重绑定。这听起来是一种有趣的方法。我可能会在某个时候调查一下(如果这里还没有人给我答案的话),但这并不太方便。创建一个转换器并使用多重绑定可能比创建一个新的依赖属性,然后处理我的示例中两个文本框的更改事件以重新计算表达式的值更容易。感谢您的示例,但是您缺少调用“PropertyChanged”表示“Height”的代码每当textBox1.Text和textBox2.Text发生更改时。如果你不这样做,用户界面将无法正确更新。@Ashley Davis:你说得对。它还缺少任何异常处理,这取决于