• WF4 AttachedPropertiesService


    在运行时给某个实例注入附件属性,主要有三个类:AttachedPropertiesService AttachedProperty AttachedProperty<T>

    下面是测试程序:

    using System;

    using System.Activities.Presentation;

    using System.Activities.Presentation.Model;

    using System.Collections.Generic;

    using System.Linq;

     

    namespace AttachedPropertiesBlogPosting

    {

        class Program

        {

            static void Main(string[] args)

            {

                EditingContext ec = new EditingContext();

                ModelTreeManager mtm = new ModelTreeManager(ec);

                mtm.Load(new object[] { new Dog { Name = "Sasha", Noise = "Snort", Age = 5 },

                                        new Cat { Name="higgs", Noise="boom", Age=1 } });

                dynamic root = mtm.Root;

                dynamic dog = root[0];

                dynamic cat = root[1];

              

                ModelItem dogMi = root[0] as ModelItem;

                ModelItem catMi = root[1] as ModelItem;

     

                // Add an attached Property

                AttachedProperty<bool> ap = new AttachedProperty<bool>

                {

                    IsBrowsable = true,

                    Name = "IsAnInterestingDog",

                    Getter = (mi => mi.Properties["Name"].ComputedValue.ToString() == "Sasha"),

                    OwnerType = typeof(Dog)

                };

                ec.Services.Publish<AttachedPropertiesService>(new AttachedPropertiesService());

                AttachedPropertiesService aps = ec.Services.GetService<AttachedPropertiesService>();

                aps.AddProperty(ap);

     

                Console.WriteLine("---- Enumerate properties on dog (note new property)----");

                dogMi.Properties.ToList().ForEach(mp => Console.WriteLine(" Property : {0}", mp.Name));

     

                Console.WriteLine("---- Enumerate properties on cat (note  no new property) ----");

                catMi.Properties.ToList().ForEach(mp => Console.WriteLine(" Property : {0}", mp.Name)); 

     

                AttachedProperty<bool> isYoungAnimal = new AttachedProperty<bool>

                {

                    IsBrowsable = false,

                    Name = "IsYoungAnimal",

                    Getter = (mi => int.Parse(mi.Properties["Age"].ComputedValue.ToString()) < 2)

                };

     

                aps.AddProperty(isYoungAnimal);

     

                // expect to not see isYoungAnimal show up

                Console.WriteLine("---- Enumerate properties on dog  (note isYoungAnimal doesn't appear )----");

                dogMi.Properties.ToList().ForEach(mp => Console.WriteLine(" Property : {0}", mp.Name));

                Console.WriteLine("---- Enumerate properties on cat (note isYoungAnimal doesn't appear )----");

                catMi.Properties.ToList().ForEach(mp => Console.WriteLine(" Property : {0}", mp.Name));

     

                Console.WriteLine("---- get attached property via GetValue ----");

                Console.WriteLine("getting non browsable attached property on dog {0}", isYoungAnimal.GetValue(dogMi));

                Console.WriteLine("getting non browsable attached property on cat {0}", isYoungAnimal.GetValue(catMi));

     

     

                // now, let's do something clever with the setter.

                Console.WriteLine("---- let's use the setter to have some side effect ----");

                isYoungAnimal.Setter = ((mi, val) => { if (val) { mi.Properties["Age"].SetValue(10); } });

                isYoungAnimal.SetValue(cat, true);

                Console.WriteLine("cat's age now {0}", cat.Age);

     

                // now, let's have a browesable one with a setter.

                // this plus dynamics are a mini "macro language" against the model items

     

                List<Object> FavoriteAnimals = new List<object>();

     

                // we maintain state in FavoriteAnimals, and use the getter/setter func

                // in order to query or edit that collection.  Thus changes to an "instance"

                // are tracked elsewhere.

                AttachedProperty<bool> isFavoriteAnimal = new AttachedProperty<bool>

                {

                    IsBrowsable = false,

                    Name = "IsFavoriteAnimal",

                    Getter = (mi => FavoriteAnimals.Contains(mi)),

                    Setter = ((mi, val) =>

                    {

                        if (val)

                            FavoriteAnimals.Add(mi);

                        else

                        {

                            FavoriteAnimals.Remove(mi);

                        }

                    })

                };

                aps.AddProperty(isFavoriteAnimal);

                dog.IsFavoriteAnimal = true;

                // remove that cat that isn't there

                cat.IsFavoriteAnimal = false;

                cat.IsFavoriteAnimal = true;

                cat.IsFavoriteAnimal = false;

                Console.WriteLine("Who are my favorite animals?");

                FavoriteAnimals.ForEach(o => Console.WriteLine((o as ModelItem).Properties["Name"].ComputedValue.ToString()));

                Console.ReadLine();

            }

        }

     

        public class Dog

        {

            public string Name { get; set; }

            public string Noise { get; set; }

            public int Age { get; set; }

        }

     

        public class Cat

        {

            public string Name { get; set; }

            public string Noise { get; set; }

            public int Age { get; set; }

        }

    }

    还可以用XAML的方式来显示属性值:

    增加一个下面的Helper

    public class Comment

        {

            static AttachableMemberIdentifier CommentTextName = new AttachableMemberIdentifier(typeof(Comment), "CommentText"); 

            public static object GetCommentText(object instance)

            {

                object viewState;

                AttachablePropertyServices.TryGetProperty(instance, CommentTextName, out viewState);

                return viewState;

            } 

            public static void SetCommentText(object instance, object value)

            {

                AttachablePropertyServices.SetProperty(instance, CommentTextName, value);

            }

     

        }

    代码如下:

      AttachableMemberIdentifier ami = new AttachableMemberIdentifier(typeof(Comment), "CommentText");

                Dog newDog = new Dog { Age = 12, Name = "Sherlock", Noise = "Hooowl" };

                AttachablePropertyServices.SetProperty(newDog, ami, "A very good dog");

                string s = XamlServices.Save(newDog);

                Console.WriteLine("XAML");

                Console.WriteLine(s);

                Dog aSecondNewDog = XamlServices.Load(new StringReader(s)) as Dog;

                string outter;

                AttachablePropertyServices.TryGetProperty(aSecondNewDog, ami, out outter);

                Console.WriteLine("read out: {0}", outter);

    输出:

    XAML

    <Dog

         Age="12"

         Comment.CommentText="A very good dog"

         Name="Sherlock"

         Noise="Hooowl"      xmlns="clr-namespace:AttachedPropertiesBlogPosting;assembly=AttachedPropertiesBlogPosting" />

    read out: A very good dog

    代码如下:

    AttachedProperty<string> Comment = new AttachedProperty<string>

                {

                    IsBrowsable = true,

                    Name = "Comment",

                    Getter = (mi =>

                    {

                        string temp;

                        AttachablePropertyServices.TryGetProperty<string>(mi.GetCurrentValue(), ami, out temp);

                        return temp;

                    }),

                    Setter = ((mi, val) => AttachablePropertyServices.SetProperty(mi.GetCurrentValue(), ami, val))

     

                };

                aps.AddProperty(Comment);

                dogMi.Properties["Comment"].SetValue("I think I like that dog");

                string xaml = XamlServices.Save(dogMi.GetCurrentValue());

                Console.WriteLine("XAML");

                Console.WriteLine(xaml);

                Console.ReadLine();

     

    输出:

    <Dog

       Age="5"

       Comment.CommentText="I think I like that dog"

       Name="Sasha"

       Noise="Snort"    xmlns="clr-namespace:AttachedPropertiesBlogPosting;assembly=AttachedPropertiesBlogPosting" />

    代码来源:

    http://blogs.msdn.com/mwinkle/archive/2009/12/06/wf4-design-time-attachedpropertiesservice-and-attached-properties.aspx

     

  • 相关阅读:
    java中Logger.getLogger(Test.class),即log4日志的使用
    System.getProperty()方法大全 (转载)
    常用MySQL函数
    MYSQL常用命令(转载)
    Oracle中与日期时间有关的运算函数
    R
    珍惜现在,感恩生活 多重背包
    Piggy-Bank 完全背包
    骨骼收集器01背包
    D
  • 原文地址:https://www.cnblogs.com/carysun/p/AttachedProperty.html
Copyright © 2020-2023  润新知