예제 #1
0
        protected void loadItem(object o, Group page, string _dataTest)
        {
            if (o == null)            //TODO:surely a threading sync problem
            {
                return;
            }
            GraphicObject g        = null;
            ItemTemplate  iTemp    = null;
            Type          dataType = o.GetType();
            string        itempKey = dataType.FullName;

            if (_dataTest != "TypeOf")
            {
                itempKey = getItempKey(dataType, o, _dataTest);
            }

            if (ItemTemplates.ContainsKey(itempKey))
            {
                iTemp = ItemTemplates [itempKey];
            }
            else
            {
                foreach (string it in ItemTemplates.Keys)
                {
                    Type t = CompilerServices.tryGetType(it);
                    if (t == null)
                    {
                        continue;
                    }
                    if (t.IsAssignableFrom(dataType))                       //TODO:types could be cached
                    {
                        iTemp = ItemTemplates [it];
                        break;
                    }
                }
                if (iTemp == null)
                {
                    iTemp = ItemTemplates ["default"];
                }
            }

            lock (IFace.LayoutMutex) {
                g = iTemp.CreateInstance();
                                #if DESIGN_MODE
                g.design_isTGItem = true;
                                #endif
                page.AddChild(g);
//				if (isPaged)
                g.LogicalParent = this;
                g.MouseDown    += itemClick;
            }

            if (iTemp.Expand != null && g is Expandable)
            {
                Expandable e = g as Expandable;
                e.Expand         += iTemp.Expand;
                e.GetIsExpandable = iTemp.HasSubItems;
            }

            g.DataSource = o;
        }
예제 #2
0
파일: ItemTemplate.cs 프로젝트: masums/Crow
        /// <summary>
        /// Creates the expand delegate.
        /// </summary>
        /// <param name="host">Host.</param>
        public void CreateExpandDelegate(TemplatedGroup host)
        {
            Type dataType = null;

            //if (host.DataTest == "TypeOf"){
            dataType = CompilerServices.tryGetType(strDataType);
//				if (dataType == null) {
//					Debug.WriteLine ("ItemTemplate error: DataType not found: {0}.", strDataType);
//					return;
//				}
//			}
            Type tmpGrpType = typeof(TemplatedGroup);
            Type evtType    = typeof(EventHandler);

            //PropertyInfo piData = tmpGrpType.GetProperty ("Data");

            MethodInfo evtInvoke = evtType.GetMethod("Invoke");

            ParameterInfo [] evtParams       = evtInvoke.GetParameters();
            Type             handlerArgsType = evtParams [1].ParameterType;

            Type [] args = { CompilerServices.TObject, CompilerServices.TObject, handlerArgsType };

            #region Expand dyn meth
            //DM is bound to templatedGroup root (arg0)
            //arg1 is the sender of the expand event
            DynamicMethod dm = new DynamicMethod("dyn_expand_" + fetchMethodName,
                                                 typeof(void), args, typeof(TemplatedGroup), true);

            System.Reflection.Emit.Label gotoEnd;
            System.Reflection.Emit.Label ifDataIsNull;
            System.Reflection.Emit.Label gotoItemsContainerNotFound;

            ILGenerator il = dm.GetILGenerator(256);
            il.DeclareLocal(typeof(GraphicObject));

            gotoEnd      = il.DefineLabel();
            ifDataIsNull = il.DefineLabel();
            gotoItemsContainerNotFound = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_1);                 //load sender of expand event
            il.Emit(OpCodes.Ldstr, "ItemsContainer"); //load name to find
            il.Emit(OpCodes.Callvirt, CompilerServices.miFindByName);
            il.Emit(OpCodes.Stloc_0);                 //save items container as loc0

            //ensure ItemsContainer is not null
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Brfalse, gotoItemsContainerNotFound);

            //check that node is not already expanded
            il.Emit(OpCodes.Ldarg_0);             //push root TemplatedGroup into the stack
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, CompilerServices.miIsAlreadyExpanded);
            il.Emit(OpCodes.Brtrue, gotoEnd);
//			il.Emit (OpCodes.Ldloc_0);
//			il.Emit (OpCodes.Callvirt, piData.GetGetMethod ());
//			il.Emit (OpCodes.Brfalse, ifDataIsNull);
//			il.Emit (OpCodes.Br, gotoEnd);

//			il.MarkLabel(ifDataIsNull);

            //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes?
//			FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates");
//			il.Emit (OpCodes.Ldloc_0);
//			il.Emit (OpCodes.Ldarg_0);
//			il.Emit (OpCodes.Ldfld, fiTemplates);
//			il.Emit (OpCodes.Stfld, fiTemplates);

            //call 'fetchMethodName' from the dataSource to build the sub nodes list
            //il.Emit (OpCodes.Ldarg_0);//load root templatedGroop

            il.Emit(OpCodes.Ldarg_0);                                    //push root TemplatedGroup into the stack
            il.Emit(OpCodes.Ldarg_1);                                    //load sender node of expand
            il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); //get the dataSource of the sender



            if (fetchMethodName != "self")              //special keyword self allows the use of recurent list<<<
            {
                if (dataType == null)
                {
                    //dataTest was not = TypeOF, so we have to get the type of data
                    //dynamically and fetch

                    il.Emit(OpCodes.Ldstr, fetchMethodName);
                    il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch);
                }
                else
                {
                    emitGetSubData(il, dataType);
                }
            }
            //set 'return' from the fetch method as 'data' of the list
            //il.Emit (OpCodes.Callvirt, piData.GetSetMethod ());
            il.Emit(OpCodes.Ldloc_0);             //load second arg of loadPage, the sender node
            il.Emit(OpCodes.Ldstr, dataTest);     //load 3rd arg, dataTest kind on subitems
            il.Emit(OpCodes.Callvirt, CompilerServices.miLoadPage);
            il.Emit(OpCodes.Br, gotoEnd);

            il.MarkLabel(gotoItemsContainerNotFound);
            il.EmitWriteLine("ItemsContainer not found in ItemTemplate for " + host.ToString());


            il.MarkLabel(gotoEnd);
            il.Emit(OpCodes.Ret);

            Expand = (EventHandler)dm.CreateDelegate(evtType, host);
            #endregion

            #region Items counting dyn method
            //dm is unbound, arg0 is instance of Item container to expand
            dm = new DynamicMethod("dyn_count_" + fetchMethodName,
                                   typeof(bool), new Type[] { CompilerServices.TObject }, true);
            il = dm.GetILGenerator(256);

            //get the dataSource of the arg0
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource);

            if (fetchMethodName != "self")              //special keyword self allows the use of recurent list<<<
            {
                if (dataType == null)
                {
                    //dataTest was not = TypeOF, so we have to get the type of data
                    //dynamically and fetch

                    il.Emit(OpCodes.Ldstr, fetchMethodName);
                    il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch);
                }
                else
                {
                    emitGetSubData(il, dataType);
                }
            }

            il.Emit(OpCodes.Callvirt, CompilerServices.miGetColCount);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Cgt);
            il.Emit(OpCodes.Ret);
            HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate(typeof(BooleanTestOnInstance));
            #endregion
        }