Exemple #1
0
        private CollectionBoxViewModel createViewModel(StackPanel control, string parent, string name, Type type, object[] attributes, IList member, bool index1)
        {
            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(IList <>), type, 0);

            CollectionBoxViewModel mv = new CollectionBoxViewModel(new StringConv(elementType, ReflectionExt.GetPassableAttributes(1, attributes)));

            mv.Index1 = index1;
            //add lambda expression for editing a single element
            mv.OnEditItem += (int index, object element, CollectionBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + index + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(1, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), element, true);

                frmData.SelectedOKEvent += () =>
                {
                    element = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), true);
                    op(index, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.LoadFromList(member);
            return(mv);
        }
Exemple #2
0
        public override void LoadWindowControls(StackPanel control, string parent, string name, Type type, object[] attributes, IPriorityList member)
        {
            LoadLabelControl(control, name);

            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(IPriorityList <>), type, 0);

            PriorityListBox          lbxValue = new PriorityListBox();
            PriorityListBoxViewModel mv       = new PriorityListBoxViewModel(new StringConv(elementType, ReflectionExt.GetPassableAttributes(2, attributes)));

            lbxValue.DataContext = mv;

            //add lambda expression for editing a single element
            mv.OnEditItem = (Priority priority, int index, object element, PriorityListBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + priority.ToString() + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(2, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), element, true);

                frmData.SelectedOKEvent += () =>
                {
                    element = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), true);
                    op(priority, index, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };
            mv.OnEditPriority = (Priority priority, int index, PriorityListBoxViewModel.EditPriorityOp op) =>
            {
                string       elementName = name + "<Priority>";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, priority, typeof(Priority), ReflectionExt.GetPassableAttributes(1, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, typeof(Priority), ReflectionExt.GetPassableAttributes(1, attributes), priority, true);

                frmData.SelectedOKEvent += () =>
                {
                    object priorityObj = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, typeof(Priority), ReflectionExt.GetPassableAttributes(1, attributes), true);
                    op(priority, index, (Priority)priorityObj);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.LoadFromList(member);
            control.Children.Add(lbxValue);
        }
Exemple #3
0
        public override void LoadWindowControls(StackPanel control, string parent, string name, Type type, object[] attributes, ISpawnRangeList member)
        {
            LoadLabelControl(control, name);

            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(ISpawnRangeList <>), type, 0);

            RangeBorderAttribute rangeAtt = ReflectionExt.FindAttribute <RangeBorderAttribute>(attributes);

            SpawnRangeListBox lbxValue = new SpawnRangeListBox();

            lbxValue.MaxHeight = 260;
            SpawnRangeListBoxViewModel mv = new SpawnRangeListBoxViewModel(new StringConv(elementType, ReflectionExt.GetPassableAttributes(1, attributes)));

            if (rangeAtt != null)
            {
                mv.Index1    = rangeAtt.Index1;
                mv.Inclusive = rangeAtt.Inclusive;
            }
            lbxValue.DataContext = mv;


            //add lambda expression for editing a single element
            mv.OnEditItem += (int index, object element, SpawnRangeListBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + index + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(2, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), element, true);

                frmData.SelectedOKEvent += () =>
                {
                    element = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), true);
                    op(index, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.LoadFromList(member);
            control.Children.Add(lbxValue);
        }
Exemple #4
0
        public override void LoadWindowControls(StackPanel control, string parent, string name, Type type, object[] attributes, IList member)
        {
            LoadLabelControl(control, name);

            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(IList <>), member.GetType(), 0);

            CollectionBox lbxValue = new CollectionBox();

            lbxValue.MaxHeight = 180;
            CollectionBoxViewModel mv = new CollectionBoxViewModel(new StringConv(elementType, ReflectionExt.GetPassableAttributes(1, attributes)));

            lbxValue.DataContext = mv;

            //add lambda expression for editing a single element
            mv.OnEditItem += (int index, object element, CollectionBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + index + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(1, attributes));

                //TODO: make this a member and reference it that way
                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), element, true);

                frmData.SelectedOKEvent += async() =>
                {
                    object newElement = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), true);

                    bool itemExists = false;

                    List <object> states = (List <object>)mv.GetList(typeof(List <object>));
                    for (int ii = 0; ii < states.Count; ii++)
                    {
                        //ignore the current index being edited
                        //if the element is null, then we are editing a new object, so skip
                        if (ii != index || element == null)
                        {
                            if (states[ii].Equals(newElement))
                            {
                                itemExists = true;
                            }
                        }
                    }

                    if (itemExists)
                    {
                        await MessageBox.Show(control.GetOwningForm(), "Cannot add duplicate states.", "Entry already exists.", MessageBox.MessageBoxButtons.Ok);
                    }
                    else
                    {
                        op(index, newElement);
                        frmData.Close();
                    }
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            List <object> states = new List <object>();

            foreach (object state in member)
            {
                states.Add(state);
            }
            mv.LoadFromList(states);
            control.Children.Add(lbxValue);
        }
        public override void LoadWindowControls(StackPanel control, string parent, string name, Type type, object[] attributes, IDictionary member)
        {
            LoadLabelControl(control, name);

            Type keyType     = ReflectionExt.GetBaseTypeArg(typeof(IDictionary <,>), type, 0);
            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(IDictionary <,>), type, 1);

            DictionaryBox lbxValue = new DictionaryBox();

            lbxValue.MaxHeight = 180;
            DictionaryBoxViewModel mv = new DictionaryBoxViewModel(control.GetOwningForm(), new StringConv(elementType, ReflectionExt.GetPassableAttributes(2, attributes)));

            lbxValue.DataContext = mv;

            //add lambda expression for editing a single element
            mv.OnEditItem += (object key, object element, DictionaryBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + key.ToString() + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(2, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), element, true);

                frmData.SelectedOKEvent += () =>
                {
                    element = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(2, attributes), true);
                    op(key, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.OnEditKey += (object key, object element, DictionaryBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "<Key>";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, key, keyType, ReflectionExt.GetPassableAttributes(1, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, keyType, ReflectionExt.GetPassableAttributes(1, attributes), key, true);

                frmData.SelectedOKEvent += () =>
                {
                    key = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, keyType, ReflectionExt.GetPassableAttributes(1, attributes), true);
                    op(key, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.LoadFromDict(member);
            control.Children.Add(lbxValue);
        }
        public override void LoadWindowControls(StackPanel control, string parent, string name, Type type, object[] attributes, IRangeDict member)
        {
            LoadLabelControl(control, name);

            Type keyType     = typeof(IntRange);
            Type elementType = ReflectionExt.GetBaseTypeArg(typeof(IRangeDict <>), type, 0);

            RangeBorderAttribute rangeAtt = ReflectionExt.FindAttribute <RangeBorderAttribute>(attributes);

            RangeDictBox lbxValue = new RangeDictBox();

            lbxValue.MaxHeight = 180;
            RangeDictBoxViewModel mv = new RangeDictBoxViewModel(control.GetOwningForm(), new StringConv(elementType, ReflectionExt.GetPassableAttributes(1, attributes)));

            if (rangeAtt != null)
            {
                mv.Index1    = rangeAtt.Index1;
                mv.Inclusive = rangeAtt.Inclusive;
            }
            lbxValue.DataContext = mv;

            //add lambda expression for editing a single element
            mv.OnEditItem += (IntRange key, object element, RangeDictBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "[" + key.ToString() + "]";
                DataEditForm frmData     = new DataEditForm();
                frmData.Title = DataEditor.GetWindowTitle(parent, elementName, element, elementType, ReflectionExt.GetPassableAttributes(1, attributes));

                DataEditor.LoadClassControls(frmData.ControlPanel, parent, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), element, true);

                frmData.SelectedOKEvent += () =>
                {
                    element = DataEditor.SaveClassControls(frmData.ControlPanel, elementName, elementType, ReflectionExt.GetPassableAttributes(1, attributes), true);
                    op(key, element);
                    frmData.Close();
                };
                frmData.SelectedCancelEvent += () =>
                {
                    frmData.Close();
                };

                control.GetOwningForm().RegisterChild(frmData);
                frmData.Show();
            };

            mv.OnEditKey += (IntRange key, object element, RangeDictBoxViewModel.EditElementOp op) =>
            {
                string       elementName = name + "<Range>";
                DataEditForm frmKey      = new DataEditForm();

                List <object> attrList = new List <object>();
                if (rangeAtt != null)
                {
                    attrList.Add(rangeAtt);
                }
                frmKey.Title = DataEditor.GetWindowTitle(parent, elementName, key, keyType, attrList.ToArray());

                DataEditor.LoadClassControls(frmKey.ControlPanel, parent, elementName, keyType, attrList.ToArray(), key, true);

                frmKey.SelectedOKEvent += () =>
                {
                    key = (IntRange)DataEditor.SaveClassControls(frmKey.ControlPanel, elementName, keyType, attrList.ToArray(), true);
                    op(key, element);
                    frmKey.Close();
                };
                frmKey.SelectedCancelEvent += () =>
                {
                    frmKey.Close();
                };

                control.GetOwningForm().RegisterChild(frmKey);
                frmKey.Show();
            };

            mv.LoadFromDict(member);
            control.Children.Add(lbxValue);
        }
Exemple #7
0
        void IEditor.LoadClassControls(StackPanel control, string parent, string name, Type type, object[] attributes, object member, bool isWindow)
        {
            //if you want a class that is by default isolated to a classbox but has a custom UI when opened on its own/overridden to render,
            //override LoadWindowControls, which is called by those methods.

            //in all cases where the class itself isn't being rendered to the window, simply represent as an editable object

            //isWindow will force subgroup automatically
            //otherwise, the presence of a Subgroup attribute will force it (or the presence of a Separation attribute will force it into its own classbox)
            //then defaultSubgroup will force it.

            bool subGroup = DefaultSubgroup;

            if (ReflectionExt.FindAttribute <SepGroupAttribute>(attributes) != null)
            {
                subGroup = false;
            }
            if (ReflectionExt.FindAttribute <SubGroupAttribute>(attributes) != null)
            {
                subGroup = true;
            }
            if (isWindow)
            {
                subGroup = true;
            }

            if (!subGroup)
            {
                LoadLabelControl(control, name);
                if (member == null)
                {
                    Type[] children;
                    if (DefaultType)
                    {
                        children = new Type[1] {
                            type
                        }
                    }
                    ;
                    else
                    {
                        children = type.GetAssignableTypes();
                    }
                    //create an empty instance
                    member = ReflectionExt.CreateMinimalInstance(children[0]);
                }

                ClassBox           cbxValue  = new ClassBox();
                MultilineAttribute attribute = ReflectionExt.FindAttribute <MultilineAttribute>(attributes);
                if (attribute != null)
                {
                    //txtValue.Multiline = true;
                    cbxValue.Height = 80;
                    //txtValue.Size = new Size(0, 80);
                }
                //else
                //    txtValue.Size = new Size(0, 20);
                ClassBoxViewModel mv = new ClassBoxViewModel(new StringConv(type, ReflectionExt.GetPassableAttributes(0, attributes)));
                mv.LoadFromSource(member);
                cbxValue.DataContext = mv;
                control.Children.Add(cbxValue);

                //add lambda expression for editing a single element
                mv.OnEditItem += (object element, ClassBoxViewModel.EditElementOp op) =>
                {
                    DataEditForm frmData = new DataEditForm();
                    frmData.Title = DataEditor.GetWindowTitle(parent, name, element, type, ReflectionExt.GetPassableAttributes(0, attributes));

                    DataEditor.LoadClassControls(frmData.ControlPanel, parent, name, type, ReflectionExt.GetPassableAttributes(0, attributes), element, true);

                    frmData.SelectedOKEvent += () =>
                    {
                        element = DataEditor.SaveClassControls(frmData.ControlPanel, name, type, ReflectionExt.GetPassableAttributes(0, attributes), true);
                        op(element);
                        frmData.Close();
                    };
                    frmData.SelectedCancelEvent += () =>
                    {
                        frmData.Close();
                    };

                    control.GetOwningForm().RegisterChild(frmData);
                    frmData.Show();
                };

                {
                    ContextMenu copyPasteStrip = new ContextMenu();

                    MenuItem copyToolStripMenuItem  = new MenuItem();
                    MenuItem pasteToolStripMenuItem = new MenuItem();

                    Avalonia.Collections.AvaloniaList <object> list = (Avalonia.Collections.AvaloniaList <object>)copyPasteStrip.Items;
                    list.AddRange(new MenuItem[] {
                        copyToolStripMenuItem,
                        pasteToolStripMenuItem
                    });

                    copyToolStripMenuItem.Header  = "Copy " + type.Name;
                    pasteToolStripMenuItem.Header = "Paste " + type.Name;

                    copyToolStripMenuItem.Click += (object copySender, RoutedEventArgs copyE) =>
                    {
                        DataEditor.SetClipboardObj(mv.Object);
                    };
                    pasteToolStripMenuItem.Click += async(object copySender, RoutedEventArgs copyE) =>
                    {
                        Type type1 = DataEditor.clipboardObj.GetType();
                        Type type2 = type;
                        if (type2.IsAssignableFrom(type1))
                        {
                            mv.LoadFromSource(DataEditor.clipboardObj);
                        }
                        else
                        {
                            await MessageBox.Show(control.GetOwningForm(), String.Format("Incompatible types:\n{0}\n{1}", type1.AssemblyQualifiedName, type2.AssemblyQualifiedName), "Invalid Operation", MessageBox.MessageBoxButtons.Ok);
                        }
                    };

                    control.ContextMenu = copyPasteStrip;
                }
            }
            else
            {
                //when being drawn as a subgroup, we have 2 options:
                //(A) include a label and border, OR
                //(B) add controls directly to the current stackpanel?

                //additionally, there will be complications when the Type for a member has child classes
                //in this case, (A) choosing to have a label and border will result in label over the type dropdown, and border in the chosen class
                //(B) choosing not to have a label and border will remove the label, but still have a dropdown and contain it a child stackpanel, without border or margin

                //when isWindow is true, we never want option A. No label, no border, no margin
                //when isWindow is false, (which means either subgroup or defaultsubgroup is active) it's up to the editor itself to decide

                bool includeDecoration = DefaultDecoration;
                if (isWindow)
                {
                    includeDecoration = false;
                }


                //if it's a class of its own, create a new panel
                //then pass it into the call
                //use the returned "ref" int to determine how big the panel should be
                //continue from there
                Type[] children;
                if (DefaultType)
                {
                    children = new Type[1] {
                        type
                    }
                }
                ;
                else
                {
                    children = type.GetAssignableTypes();
                }

                //handle null members by getting an instance of the FIRST instantiatable subclass (including itself) it can find
                if (member == null)
                {
                    member = ReflectionExt.CreateMinimalInstance(children[0]);
                }

                if (children.Length < 1)
                {
                    throw new Exception("Completely abstract field found for: " + name);
                }
                else if (children.Length == 1)
                {
                    Type memberType = member.GetType();
                    if (children[0] != memberType)
                    {
                        throw new TargetException("Types do not match.");
                    }

                    StackPanel controlParent = control;
                    if (includeDecoration)
                    {
                        LoadLabelControl(control, name);

                        Border border = new Border();
                        border.BorderThickness = new Thickness(1);
                        border.BorderBrush     = Avalonia.Media.Brushes.LightGray;
                        border.Margin          = new Thickness(2);
                        control.Children.Add(border);

                        StackPanel groupBoxPanel = new StackPanel();
                        groupBoxPanel.Margin = new Thickness(2);
                        border.Child         = groupBoxPanel;

                        controlParent = groupBoxPanel;
                    }

                    {
                        ContextMenu copyPasteStrip = new ContextMenu();

                        MenuItem copyToolStripMenuItem  = new MenuItem();
                        MenuItem pasteToolStripMenuItem = new MenuItem();

                        Avalonia.Collections.AvaloniaList <object> list = (Avalonia.Collections.AvaloniaList <object>)copyPasteStrip.Items;
                        list.AddRange(new MenuItem[] {
                            copyToolStripMenuItem,
                            pasteToolStripMenuItem
                        });

                        copyToolStripMenuItem.Header  = "Copy " + type.Name;
                        pasteToolStripMenuItem.Header = "Paste " + type.Name;

                        copyToolStripMenuItem.Click += (object copySender, RoutedEventArgs copyE) =>
                        {
                            object obj = DataEditor.SaveWindowControls(controlParent, name, children[0], attributes);
                            DataEditor.SetClipboardObj(obj);
                        };
                        pasteToolStripMenuItem.Click += async(object copySender, RoutedEventArgs copyE) =>
                        {
                            Type type1 = DataEditor.clipboardObj.GetType();
                            Type type2 = type;
                            if (type2.IsAssignableFrom(type1))
                            {
                                controlParent.Children.Clear();
                                DataEditor.LoadWindowControls(controlParent, parent, name, type1, attributes, DataEditor.clipboardObj);
                            }
                            else
                            {
                                await MessageBox.Show(control.GetOwningForm(), String.Format("Incompatible types:\n{0}\n{1}", type1.AssemblyQualifiedName, type2.AssemblyQualifiedName), "Invalid Operation", MessageBox.MessageBoxButtons.Ok);
                            }
                        };

                        control.ContextMenu = copyPasteStrip;
                    }
                    controlParent.Background = Avalonia.Media.Brushes.Transparent;
                    DataEditor.LoadWindowControls(controlParent, parent, name, children[0], attributes, member);
                }
                else
                {
                    //note: considerations must be made when dealing with inheritance/polymorphism
                    //eg: find all children in this assembly that can be instantiated,
                    //add them to different panels
                    //show the one that is active right now
                    //include a combobox for switching children

                    StackPanel controlParent = null;
                    if (includeDecoration)
                    {
                        LoadLabelControl(control, name);
                    }

                    Grid sharedRowPanel = getSharedRowPanel(2);

                    TextBlock lblType = new TextBlock();
                    lblType.Text = "Type:";
                    lblType.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center;
                    sharedRowPanel.Children.Add(lblType);
                    sharedRowPanel.ColumnDefinitions[0].Width = new GridLength(30);
                    lblType.SetValue(Grid.ColumnProperty, 0);

                    ComboBox cbValue = new ComboBox();
                    cbValue.Margin             = new Thickness(4, 0, 0, 0);
                    cbValue.VirtualizationMode = ItemVirtualizationMode.Simple;
                    sharedRowPanel.Children.Add(cbValue);
                    cbValue.SetValue(Grid.ColumnProperty, 1);

                    control.Children.Add(sharedRowPanel);


                    if (includeDecoration)
                    {
                        Border border = new Border();
                        border.BorderThickness = new Thickness(1);
                        border.BorderBrush     = Avalonia.Media.Brushes.LightGray;
                        border.Margin          = new Thickness(2);
                        control.Children.Add(border);

                        StackPanel groupBoxPanel = new StackPanel();
                        groupBoxPanel.Margin = new Thickness(2);
                        border.Child         = groupBoxPanel;

                        controlParent = groupBoxPanel;
                    }
                    else
                    {
                        StackPanel groupBoxPanel = new StackPanel();
                        control.Children.Add(groupBoxPanel);
                        controlParent = groupBoxPanel;
                    }



                    List <CreateMethod> createMethods = new List <CreateMethod>();

                    bool          refreshPanel = true;
                    List <string> items        = new List <string>();
                    int           selection    = -1;
                    for (int ii = 0; ii < children.Length; ii++)
                    {
                        Type childType = children[ii];
                        items.Add(childType.GetDisplayName());

                        createMethods.Add(() =>
                        {
                            if (refreshPanel)
                            {
                                controlParent.Children.Clear();
                                object emptyMember = ReflectionExt.CreateMinimalInstance(childType);
                                DataEditor.LoadWindowControls(controlParent, parent, name, childType, attributes, emptyMember);//TODO: POTENTIAL INFINITE RECURSION?
                            }
                        });
                        if (childType == member.GetType())
                        {
                            selection = ii;
                        }
                    }
                    if (selection == -1)
                    {
                        throw new TargetException("Types do not match.");
                    }

                    var subject = new Subject <List <string> >();
                    cbValue.Bind(ComboBox.ItemsProperty, subject);
                    subject.OnNext(items);
                    cbValue.SelectedIndex = selection;

                    cbValue.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
                    {
                        createMethods[cbValue.SelectedIndex]();
                    };

                    {
                        ContextMenu copyPasteStrip = new ContextMenu();

                        MenuItem copyToolStripMenuItem  = new MenuItem();
                        MenuItem pasteToolStripMenuItem = new MenuItem();

                        Avalonia.Collections.AvaloniaList <object> list = (Avalonia.Collections.AvaloniaList <object>)copyPasteStrip.Items;
                        list.AddRange(new MenuItem[] {
                            copyToolStripMenuItem,
                            pasteToolStripMenuItem
                        });

                        copyToolStripMenuItem.Header  = "Copy " + type.Name;
                        pasteToolStripMenuItem.Header = "Paste " + type.Name;

                        copyToolStripMenuItem.Click += (object copySender, RoutedEventArgs copyE) =>
                        {
                            object obj = DataEditor.SaveWindowControls(controlParent, name, children[cbValue.SelectedIndex], attributes);
                            DataEditor.SetClipboardObj(obj);
                        };
                        pasteToolStripMenuItem.Click += async(object copySender, RoutedEventArgs copyE) =>
                        {
                            Type type1    = DataEditor.clipboardObj.GetType();
                            Type type2    = type;
                            int  type_idx = -1;
                            for (int ii = 0; ii < children.Length; ii++)
                            {
                                if (children[ii] == type1)
                                {
                                    type_idx = ii;
                                    break;
                                }
                            }
                            if (type_idx > -1)
                            {
                                refreshPanel          = false;
                                cbValue.SelectedIndex = type_idx;
                                refreshPanel          = true;

                                controlParent.Children.Clear();
                                DataEditor.LoadWindowControls(controlParent, parent, name, type1, attributes, DataEditor.clipboardObj);
                            }
                            else
                            {
                                await MessageBox.Show(control.GetOwningForm(), String.Format("Incompatible types:\n{0}\n{1}", type1.AssemblyQualifiedName, type2.AssemblyQualifiedName), "Invalid Operation", MessageBox.MessageBoxButtons.Ok);
                            }
                        };

                        control.ContextMenu = copyPasteStrip;
                    }
                    controlParent.Background = Avalonia.Media.Brushes.Transparent;
                    DataEditor.LoadWindowControls(controlParent, parent, name, children[selection], attributes, member);
                }
            }
        }