예제 #1
0
        protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e)
        {
            if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content")
            {
                LimeMsg.Debug("LimeListView OnPropertyChanged: {0} : {1} : {2}", prop, prop?.Ident, e?.PropertyName);

                int idx = 0;

                // Bellow we try to re-use the existing controls to avoid rendering overhead

                if (prop != null)
                {
                    LimePropertyCollection collec;

                    if (typeof(LimePropertyCollection).IsAssignableFrom(prop.Type))
                    {
                        collec = (LimePropertyCollection)prop.Content;
                    }
                    else
                    {
                        collec = new LimePropertyCollection(null, prop);
                    }

                    for (int i = 0; i < collec.Count; i++)
                    {
                        var         sprop  = collec[i];
                        LimeControl wxctrl = null;
                        var         type   = LimeControlSelector(sprop);
                        if (type == null)
                        {
                            continue;
                        }

                        if (idx < wxMain.Items.Count)
                        {
                            var wxitem   = (LimeControl)wxMain.Items[idx];
                            var propitem = (LimeProperty)wxitem.DataContext;
                            if (type == wxitem.GetType())
                            {
                                LimeMsg.Debug("LimeListView OnPropertyChanged: recycle {0} : {1} --> {2}", idx, propitem, sprop);
                                wxitem.DataContext = sprop;
                                wxitem.Visibility  = sprop?.Visible == true ? Visibility.Visible : Visibility.Collapsed;
                            }
                            else
                            {
                                LimeMsg.Debug("LimeListView OnPropertyChanged: replaced {0} : {1} --> {2}", idx, propitem, sprop);
                                wxMain.Items[idx] = wxctrl = (LimeControl)Activator.CreateInstance(type);
                            }
                        }
                        else
                        {
                            LimeMsg.Debug("LimeListView OnPropertyChanged: new {0} : {1}", idx, sprop);
                            wxMain.Items.Add(wxctrl = (LimeControl)Activator.CreateInstance(type));
                        }

                        if (wxctrl != null)
                        {
                            wxctrl.IsTabStop        = false;
                            wxctrl.Level            = Level > 0.11 ? Level - 0.1 : Level;
                            wxctrl.ReadOnly         = ReadOnly;
                            wxctrl.HeaderEnabled    = HeaderEnabled;
                            wxctrl.ValidateOnChange = ValidateOnChange;
                            wxctrl.DataContext      = sprop;
                        }

                        idx++;
                    }
                }

                // Hide remaining items from previous bindings
                for (; idx < wxMain.Items.Count; idx++)
                {
                    var wxitem = (LimeControl)wxMain.Items[idx];
                    wxitem.DataContext = null;
                    wxitem.Visibility  = Visibility.Collapsed;
                }
            }
        }
예제 #2
0
        private static void OnBoundDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var wxThis        = d as LimeControl;
            var isLimeControl = wxThis != null && wxThis.GetType() == typeof(LimeControl);

            //LimeMsg.Debug("LimeControl OnBoundDataContextChanged: {0}", e.NewValue);
            if (e.OldValue is LimeProperty old)
            {
                old.PropertyChangedWeak -= wxThis.TriggerDataContextChanged;
            }

            var prop    = e.NewValue as LimeProperty;
            var content = prop != null ? prop.Content : e.NewValue;

            // Unpack from Matryoshka
            if (content is IMatryoshka matr)
            {
                // Find the most inner matryoshka object
                while (matr.Content is IMatryoshka sub)
                {
                    matr = sub;
                }
                content = matr.Content;

                // Repack into a LimeProperty
                if (prop != null)
                {
                    prop = new LimeProperty(null, matr, "Content", prop);
                }
                else
                {
                    prop = new LimeProperty(null, matr, "Content");
                }
            }

            // Encapsulate into LimeProperty
            if (prop == null && content != null)
            {
                prop = new LimeProperty(null, content);
                e    = new DependencyPropertyChangedEventArgs(e.Property, e.OldValue, prop);
            }

            // Select the right LimeControl sub-class depending on the Type of the LimeProperty
            LimeControl wxbind = wxThis;

            if (isLimeControl)
            {
#if DEBUG
                wxThis.ADebug = prop != null?string.Format("{1} [{0}] (base)", prop.Type, prop.Ident ?? prop.Name) : "null (base)";
#endif
                // Type dispatcher
                var type = LimeControlSelector(prop);

                LimeControl wxobj = null;
                if (type == null)
                {
                    // do nothing
                }
                else if (type != wxThis.Content?.GetType())
                {
                    wxobj      = (LimeControl)Activator.CreateInstance(type);
                    wxobj.Base = wxThis;
                }
                else
                {
                    wxobj = (LimeControl)wxThis.Content;
                }

                wxThis.Content = wxbind = wxobj;

#if DEBUG
                if (wxobj != null)
                {
                    wxobj.ADebug = prop != null?string.Format("{1} [{0}] (content)", prop.Type, prop.Ident ?? prop.Name) : "null (content)";
                }
#endif
            }

            // Bind property to this Control (or content)
            if (prop != null)
            {
                prop.PropertyChangedWeak += wxbind.TriggerDataContextChanged;
            }

            if (wxThis != null && wxThis.Content is FrameworkElement wxcont)
            {
                wxcont.DataContext = prop;
            }

            // Event trigger
            wxbind?.OnBoundDataContextChanged(e);


            if (!isLimeControl && wxbind != null)
            {
                // Trigger Binding initialization
                wxbind.TriggerDataContextChanged(prop, new PropertyChangedEventArgs(null));
            }
        }