如何使用 System.Activities.Validation.GetParentChain? [英] How do I use System.Activities.Validation.GetParentChain?

查看:20
本文介绍了如何使用 System.Activities.Validation.GetParentChain?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Outer Activity,它有一个 Body,你可以将其他 Activity 拖到它上面.然后我有几个内部活动,它们必须是外部活动的后代.我想添加设计时验证以确保将内部放置在外部.

I've got an Outer activity which has a Body onto which you drag other activities. I then have several Inner activities, which MUST be a descendent of an Outer activity. I'd like to add design-time validation to ensure the Inner is placed within an Outer.

我听说我可以使用 System.Activities.Validation.GetParentChain 在验证步骤中枚举活动的所有父项".但即使阅读了该课程的文档,我不知道如何使用它.

I've heard that I "can use System.Activities.Validation.GetParentChain to enumerate all of the parents of an activity during the validation step". But even after reading the documentation for the class, I have no idea how to use it.

我想我在内部类的 CacheMetadata 中使用它.我想使用 foreach(varances in parentChain) { ... },并确保至少有一个祖先是 Outer 类型的.不知道该怎么做.

I would think I use it inside CacheMetadata in my Inner class. I'd like to use have a foreach(var ancestor in parentChain) { ... }, and make sure at least one ancestor is of type Outer. Not sure how to do that.

谁能解释一下如何在设计时验证内部活动是外部活动的后代?

Can anyone explain how to validate at design time that an Inner activity is a descendant of an Outer activity?

推荐答案

正如您通过 documentation GetParentChain 是一个常规的 CodeActivity.您可以将它与 Activity.Constraints 结合使用.

As you can see through the documentation GetParentChain is a regular CodeActivity. You can use it in conjunction with Activity.Constraints.

约束在设计时执行,就像 CacheMetadata(),但您可以访问上下文(当然,此时是 ValidationContext).否则你将无法知道上层活动.

Constraints are executed at design time, just like CacheMetadata(), but you have the ability to access the context (the ValidationContext at this point, of course). Otherwise you wouldn't be able to known the upper level activities.

让我们看看我是否理解你的情况,以及这个例子是否涵盖了它.基本上,它循环遍历 GetParentChain 返回的 IEnumerable 并检查 Inner 的父节点是否是 Outer>.这样可以确保 Inner 始终位于 Outer 之内.

Lets see if I understood your case right and if this example covers it. Basically it loops through IEnumerable<Activity> returned by GetParentChain and checks if any of Inner's parents is an Outer. This way it ensures that Inner is always inside an Outer.

public sealed class Inner : CodeActivity
{

    public Inner()
    {
        Constraints.Add(MustBeInsideOuterActivityConstraint());
    }

    protected override void Execute(CodeActivityContext context)
    {
        // Execution logic here
    }

    private Constraint<Inner> MustBeInsideOuterActivityConstraint()
    {
        var activityBeingValidated = new DelegateInArgument<Inner>();
        var validationContext = new DelegateInArgument<ValidationContext>();
        var parent = new DelegateInArgument<Activity>();
        var parentIsOuter = new Variable<bool>();

        return new Constraint<Inner>
        {
            Body = new ActivityAction<Inner, ValidationContext>
            {
                Argument1 = activityBeingValidated,
                Argument2 = validationContext,

                Handler = new Sequence
                {
                    Variables = 
                    {
                        parentIsOuter
                    },
                    Activities =
                    {
                        new ForEach<Activity>
                        {
                            Values = new GetParentChain 
                            { 
                                ValidationContext = validationContext 
                            },

                            Body = new ActivityAction<Activity>
                            {
                                Argument = parent,

                                Handler = new If
                                {
                                    Condition = new InArgument<bool>(env => 
                                        object.Equals(parent.Get(env).GetType(), typeof(Outer))),

                                    Then = new Assign<bool> 
                                    { 
                                        To = parentIsOuter, 
                                        Value = true 
                                    }
                                }    
                            }
                        },

                        new AssertValidation
                        {
                            Assertion = parentIsOuter,
                            Message = "Inner must be inside Outer"
                        }
                    }
                }
            }
        };
    }
}

如果你想允许多个外层,你必须一个一个地检查它们,用循环遍历数组(使用 ForEach)或多个嵌套的 Ifs.

If you want to allow multiple Outers, you have to check them, one by one, wither with a loop through an array (using ForEach) or multiple nested Ifs.

例如,有多个 if,并继续上面的代码:

For example, with multiple ifs, and continuing with the code above:

Handler = new If
{
    Condition = new InArgument<bool>(env => 
        object.Equals(parent.Get(env).GetType(), typeof(OuterONE))),

    Then = new Assign<bool> 
    { 
        To = parentIsOuter, 
        Value = true 
    }
    Else = new If
    {
         Condition = new InArgument<bool>(env => 
             object.Equals(parent.Get(env).GetType(), typeof(OuterTWO))),

         Then = new Assign<bool> 
         { 
            To = parentIsOuter, 
            Value = true 
         },

         Else = new If 
         {
             // and continue with other Outers
         }
    }
} 

简而言之,使用活动的 If-then-else 语句.

In short, an If-then-else statement using activities.

我从未测试过但看起来很合理的其他选项,并且因为您可以在约束内使用活动,所以将所有这些逻辑都扔到一个活动中,它的唯一工作是检查是否键入外部:

Other option that I've never tested but that it seems pretty plausible, and because you can use activities inside constraints, is throw all this logic inside an activity which its only job is to check if type if an Outer:

public sealed CheckIfTypeIsOuter<T> : CodeActivity<bool>
{
    protected override bool Execute() 
    {
        if (typeof(T) == typeof(Outer1))
            return true;
        if (typeof(T) == typeof(Outer2))
            return true;
        if (typeof(T) == typeof(Outer3))
            return true;
        if (typeof(T) == typeof(Outer4))
            return true;

        return false;
    }
}

这样你就可以通过代码来实现了.

This way you can do it through code.

好吧,我想你明白了!

这篇关于如何使用 System.Activities.Validation.GetParentChain?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆