博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

ExpressionTextBox 101

Posted on 2009-11-13 21:05  生鱼片  阅读(2834)  评论(10编辑  收藏  举报

作者Cathy Dumas Workflow Designer团队的一个程序经理。

原文地址:http://blogs.msdn.com/cathyk/archive/2009/11/12/expressiontextbox-101.aspx

 

ExpressionTextBox是我们在自定义活动设计器中编辑表达式的基本构造块。 如果您正在编写一个自定义活动设计器并且使用了表达式,您将会使用此控件。 这篇文章的目的是为了给自定义活动设计器开发人员一个概述。 我会对SDK的例子做少量的解释并一步一步深入。要想跳过这篇文章你只要看下SDK中的例子ExpressionTextBoxSample就可以了。
 

开始设计一个活动设计器,首先要引入下面的命名空间:

<sap:ActivityDesigner x:Class="Microsoft.Samples.ExpressionTextBoxSample.MultiAssignDesigner"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:s="clr-namespace:System;assembly=mscorlib"

    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"

    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"

    xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"> 

表达式绑定到参数要使用ArgumentToExpressionConverter,该类位于System.Activities.Presentation.Converters命名空间中。将此转换器加入到你的资源字典中,如下所示:

 <sap:ActivityDesigner.Resources>

    <ResourceDictionary>

        <sapc:ArgumentToExpressionConverter x: Key="ArgumentToExpressionConverter" />

    </ResourceDictionary>

</sap:ActivityDesigner.Resources> 

现在你可以继续添加你的ExpressionTextBox 首先,你需要确定你所编辑的是哪种类型的表达式。 您可以在ExpressionTextBox中编辑两种类型的表达式,location expressions ( L-value expressions) value expressions. value expressions的计算结果为一个的值的表达式,可以将它们放在赋值语句的右侧, InArguments 对应值的表达式,它们被序列化为 VisualBasicValue 表达式  现在我们假设有一个 String 类型的 名为FooValue InArgument 的活动。 下面是一个简单的绑定到该参数的ExpressionTextBox 

<sapv:ExpressionTextBox

    Expression="{Binding Path=ModelItem.FooValue, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"

    ExpressionType="s:String"

    OwnerActivity="{Binding Path=ModelItem}" /> 

ExpressionOwnerActivity是必须要设置的,ExpressionType的设置也很重要,否则会有一些不稳定的行为。Path是你要绑定的参数,Mode一般都设置为TwoWay,然后我们将 In 参数传递给ArgumentToExpressionConverter告诉我们绑定到一个 InArgument 

反之,location expressions对应于OutArguments,它们被序列化为 VisualBasicReference 表达式 。你可以将location expressions放在赋值语句左侧。现在我们假设有一个 String 类型的名为FooReference OutArgument 的活动。下面是一个简单的绑定到该参数的ExpressionTextBox

<sapv:ExpressionTextBox

      Expression="{Binding Path=ModelItem.FooReference, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=Out }"

      OwnerActivity="{Binding Path=ModelItem}"

      ExpressionType="s:String"

      UseLocationExpression="True" /> 

前面的示例中有两个差异。 由于我们绑定到L-value expressionUseLocationExpression 属性设置为 True 因为我们绑定到一个 OutArgument ConverterParameter Out

还有一点我会放到另一篇文章中,绑定 ExpressionTextBoxes CLR 属性和绑定到 untyped 参数。

 

译者注:

1.       ArgumentToExpressionConverter是当绑定表达式到参数时的类型转换器。 ConverterParameter只支持In Out不支持InOut

2.       UseLocationExpression 属性用在OutArguments 来指定L-value (“left value” “location value”) 表达式时。

 

下面是作者文中提到的SDK中的例子,例子中开发了一个自定义的MultiAssign活动。

1.xaml如下:

    <sad:ActivityDesigner x:Class="Microsoft.Samples.ExpressionTextBoxSample.MultiAssignDesigner"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:sad="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"

    xmlns:sadv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"

    xmlns:sadc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"> 

    <sad:ActivityDesigner.Resources>

        <ResourceDictionary>

            <sadc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />

        </ResourceDictionary>

    </sad:ActivityDesigner.Resources>   

    <Grid>

        <Grid.ColumnDefinitions>

            <ColumnDefinition />

            <ColumnDefinition />

            <ColumnDefinition />

        </Grid.ColumnDefinitions>       

        <Grid.RowDefinitions>

            <RowDefinition/>

            <RowDefinition/>

        </Grid.RowDefinitions>             

        <sadv:ExpressionTextBox

          HintText="To"

          Expression="{Binding Path=ModelItem.To1, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=Out }"

          OwnerActivity="{Binding Path=ModelItem}"

          UseLocationExpression="True"

          Width="110"

          Margin="0,5"

          Grid.Row="0"

          Grid.Column="0"

          MaxLines="1" />       

        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="=" Grid.Row ="0" Grid.Column="1"/>                

        <sadv:ExpressionTextBox

        Expression="{Binding Path=ModelItem.Value1, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"

        OwnerActivity="{Binding Path=ModelItem}"       

        Width="110"

        Margin="0,5"

        Grid.Row="0"

        Grid.Column="2"

        MaxLines="1" /> 

        <sadv:ExpressionTextBox

          HintText="To"

          Expression="{Binding Path=ModelItem.To2, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=Out }"

          OwnerActivity="{Binding Path=ModelItem}"

          UseLocationExpression="True"

          Width="110"

          Margin="0,5"

          Grid.Row="1"

          Grid.Column="0"

          MaxLines="1" /> 

        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="=" Grid.Row ="1" Grid.Column="1"/>               

        <sadv:ExpressionTextBox

        Expression="{Binding Path=ModelItem.Value2, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"

        OwnerActivity="{Binding Path=ModelItem}"

        Width="110"

        Margin="0,5"

        Grid.Row="1"

        Grid.Column="2"

        MaxLines="1" />

    </Grid>

</sad:ActivityDesigner> 

3.        如下图:

clip_image002 

4.        代码如下:

[Designer(typeof(MultiAssignDesigner))]

    public sealed class MultiAssign : CodeActivity

    {

        [DefaultValue((string)null), RequiredArgument]

        public OutArgument To1 { get; set; } 

        public OutArgument To2 { get; set; } 

        [DefaultValue((string)null), RequiredArgument]

        public InArgument Value1 { get; set; }

        public InArgument Value2 { get; set; }         

        protected override void Execute(CodeActivityContext context)

        {

            // Obtain the runtime value of the arguments

            this.To1.Set(context, this.Value1.Get(context));

            this.To2.Set(context, this.Value2.Get(context));

        }

    }