AddValueChanged of dependency property descriptor results in memory leak as you already know. So, as described here, you can create custom class PropertyChangeNotifier to listen to any dependency property changes. This class takes advantage of the fact that bindings use weak references to manage associations so the class will not root the object who property changes it is watching. It also uses a WeakReference to maintain a reference to the object whose property it is watching without rooting that object. In this way, you can maintain a collection of these objects so that you can unhook the property change later without worrying about that collection rooting the object whose values you are watching. Complete implementation can be found here: http://agsmith.wordpress.com/2008/04/07/propertydescriptor-addvaluechanged-alternative/
Наследование: System.Windows.DependencyObject, IDisposable
Пример #1
0
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            this.hwndSource = (HwndSource)PresentationSource.FromVisual(this);
            if (this.hwndSource == null)
            {
                return;
            }

            var ws   = this.hwndSource.Handle.GetWindowLong();
            var wsex = this.hwndSource.Handle.GetWindowLongEx();

            ws |= WS.POPUP;

            wsex &= ~WSEX.APPWINDOW;
            wsex |= WSEX.TOOLWINDOW;

            if (this._owner.ResizeMode == ResizeMode.NoResize || this._owner.ResizeMode == ResizeMode.CanMinimize)
            {
                wsex |= WSEX.TRANSPARENT;
            }

            this.hwndSource.Handle.SetWindowLong(ws);
            this.hwndSource.Handle.SetWindowLongEx(wsex);
            this.hwndSource.AddHook(this.WndProc);

            this.handle      = this.hwndSource.Handle;
            this.ownerHandle = new WindowInteropHelper(this._owner).Handle;

            this.resizeModeChangeNotifier = new PropertyChangeNotifier(this._owner, ResizeModeProperty);
            this.resizeModeChangeNotifier.ValueChanged += this.ResizeModeChanged;
        }
Пример #2
0
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            this.hwndSource = (HwndSource)PresentationSource.FromVisual(this);
            if (this.hwndSource == null)
            {
                return;
            }
            WS   windowLong   = this.hwndSource.Handle.GetWindowLong();
            WSEX windowLongEx = this.hwndSource.Handle.GetWindowLongEx();

            windowLongEx ^= WSEX.APPWINDOW;
            windowLongEx |= WSEX.NOACTIVATE;
            if (base.Owner.ResizeMode == System.Windows.ResizeMode.NoResize || base.Owner.ResizeMode == System.Windows.ResizeMode.CanMinimize)
            {
                windowLongEx |= WSEX.TRANSPARENT;
            }
            this.hwndSource.Handle.SetWindowLong(windowLong);
            this.hwndSource.Handle.SetWindowLongEx(windowLongEx);
            this.hwndSource.AddHook(new HwndSourceHook(this.WndProc));
            this.handle      = this.hwndSource.Handle;
            this.ownerHandle = (new WindowInteropHelper(base.Owner)).Handle;
            this.resizeModeChangeNotifier = new PropertyChangeNotifier(base.Owner, Window.ResizeModeProperty);
            this.resizeModeChangeNotifier.ValueChanged += new EventHandler(this.ResizeModeChanged);
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HamburgerMenu"/> class.
        /// </summary>
        public HamburgerMenu()
        {
            this.DefaultStyleKey = typeof(HamburgerMenu);

            this.actualWidthPropertyChangeNotifier = new PropertyChangeNotifier(this, ActualWidthProperty);
            this.actualWidthPropertyChangeNotifier.ValueChanged += (s, e) => this.CoerceValue(OpenPaneLengthProperty);
        }
Пример #4
0
        private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
        {
            if (container != null)
            {
                if (null == item)
                {
                    // if item is not a UIElement then maybe the ItemsSource binds to a collection of objects
                    // and an ItemTemplate is set, so let's try to solve this
                    container.ApplyTemplate();
                    var content = container.ContentTemplate?.LoadContent() as UIElement;
                    if (null == content)
                    {
                        // no UIElement was found, so don't show this container
                        container.Visibility = Visibility.Collapsed;
                    }

                    return;
                }

                container.Visibility = item.Visibility;
                var isVisibilityNotifier = new PropertyChangeNotifier(item, VisibilityProperty);
                isVisibilityNotifier.ValueChanged         += this.VisibilityPropertyChanged;
                container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
            }
        }
Пример #5
0
        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PropertyChangeNotifier propertyChangeNotifier = (PropertyChangeNotifier)d;

            if (propertyChangeNotifier.ValueChanged != null)
            {
                propertyChangeNotifier.ValueChanged(propertyChangeNotifier.PropertySource, EventArgs.Empty);
            }
        }
Пример #6
0
        private void AttachHandlers(Flyout flyout)
        {
            var isOpenNotifier = new PropertyChangeNotifier(flyout, Flyout.IsOpenProperty);
            isOpenNotifier.ValueChanged += FlyoutStatusChanged;
            flyout.IsOpenPropertyChangeNotifier = isOpenNotifier;

            var themeNotifier = new PropertyChangeNotifier(flyout, Flyout.ThemeProperty);
            themeNotifier.ValueChanged += FlyoutStatusChanged;
            flyout.ThemePropertyChangeNotifier = themeNotifier;
        }
Пример #7
0
        private void AttachHandlers(Flyout flyout)
        {
            PropertyChangeNotifier propertyChangeNotifier = new PropertyChangeNotifier(flyout, Flyout.IsOpenProperty);

            propertyChangeNotifier.ValueChanged += new EventHandler(this.FlyoutStatusChanged);
            flyout.IsOpenPropertyChangeNotifier  = propertyChangeNotifier;
            PropertyChangeNotifier propertyChangeNotifier1 = new PropertyChangeNotifier(flyout, Flyout.ThemeProperty);

            propertyChangeNotifier1.ValueChanged += new EventHandler(this.FlyoutStatusChanged);
            flyout.ThemePropertyChangeNotifier    = propertyChangeNotifier1;
        }
Пример #8
0
        private void AttachHandlers(Flyout flyout)
        {
            var isOpenNotifier = new PropertyChangeNotifier(flyout, Flyout.IsOpenProperty);

            isOpenNotifier.ValueChanged        += FlyoutStatusChanged;
            flyout.IsOpenPropertyChangeNotifier = isOpenNotifier;

            var themeNotifier = new PropertyChangeNotifier(flyout, Flyout.ThemeProperty);

            themeNotifier.ValueChanged        += FlyoutStatusChanged;
            flyout.ThemePropertyChangeNotifier = themeNotifier;
        }
Пример #9
0
 private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
 {
     if (container != null)
     {
         if (item == null)
         {
             container.Visibility = System.Windows.Visibility.Collapsed;
             return;
         }
         container.Visibility = item.Visibility;
         PropertyChangeNotifier propertyChangeNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
         propertyChangeNotifier.ValueChanged       += new EventHandler(this.VisibilityPropertyChanged);
         container.VisibilityPropertyChangeNotifier = propertyChangeNotifier;
     }
 }
Пример #10
0
        private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
        {
            if (container != null)
            {
                // hide the container, if there is no UIElement
                if (null == item)
                {
                    container.Visibility = Visibility.Collapsed;
                    return;
                }

                container.Visibility = item.Visibility;
                var isVisibilityNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
                isVisibilityNotifier.ValueChanged         += VisibilityPropertyChanged;
                container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
            }
        }
        private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
        {
            if (container != null)
            {
                // hide the container, if there is no UIElement
                if (null == item)
                {
                    container.Visibility = Visibility.Collapsed;
                    return;
                }

                container.Visibility = item.Visibility;
                var isVisibilityNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
                isVisibilityNotifier.ValueChanged += VisibilityPropertyChanged;
                container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
            }
        }
Пример #12
0
 public ToggleSwitchButton()
 {
     isCheckedPropertyChangeNotifier = new PropertyChangeNotifier(this, ToggleSwitchButton.IsCheckedProperty);
     isCheckedPropertyChangeNotifier.ValueChanged += IsCheckedPropertyChangeNotifierValueChanged;
 }
Пример #13
0
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            this.hwndSource = (HwndSource)PresentationSource.FromVisual(this);
            if (hwndSource == null) return;
            
            var ws = hwndSource.Handle.GetWindowLong();
            var wsex = hwndSource.Handle.GetWindowLongEx();

            //ws |= WS.POPUP;
            wsex ^= WSEX.APPWINDOW;
            wsex |= WSEX.NOACTIVATE;
            if (this.Owner.ResizeMode == ResizeMode.NoResize || this.Owner.ResizeMode == ResizeMode.CanMinimize)
            {
                wsex |= WSEX.TRANSPARENT;
            }

            hwndSource.Handle.SetWindowLong(ws);
            hwndSource.Handle.SetWindowLongEx(wsex);
            hwndSource.AddHook(WndProc);

            handle = hwndSource.Handle;
            ownerHandle = new WindowInteropHelper(Owner).Handle;

            this.resizeModeChangeNotifier = new PropertyChangeNotifier(this.Owner, Window.ResizeModeProperty);
            this.resizeModeChangeNotifier.ValueChanged += ResizeModeChanged;
        }
Пример #14
0
 public ToggleSwitchButton()
 {
     isCheckedPropertyChangeNotifier = new PropertyChangeNotifier(this, ToggleSwitchButton.IsCheckedProperty);
     isCheckedPropertyChangeNotifier.ValueChanged += IsCheckedPropertyChangeNotifierValueChanged;
 }
Пример #15
0
        private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
        {
            if (container != null)
            {
                if (null == item)
                {
                    // if item is not a UIElement then maybe the ItemsSource binds to a collection of objects
                    // and an ItemTemplate is set, so let's try to solve this
                    container.ApplyTemplate();
                    var content = container.ContentTemplate?.LoadContent() as UIElement;
                    if (null == content)
                    {
                        // no UIElement was found, so don't show this container
                        container.Visibility = Visibility.Collapsed;
                    }
                    return;
                }

                container.Visibility = item.Visibility;
                var isVisibilityNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
                isVisibilityNotifier.ValueChanged += VisibilityPropertyChanged;
                container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
            }
        }