Search code examples
c#wpfattachedbehaviors

Resizing a Popup via Thumb with attached behavior


As shown below I have a Popup that I would like to resize with a thumb in the bottom-right hand corner. The thumb has an attached behavior that I would like to do the resizing.

<Popup x:Name="Popbox" Placement="Mouse" StaysOpen="False" Width="50" Height="50" >
    <Grid>
        <Border Background="AliceBlue"/>
        <Thumb HorizontalAlignment="Right" 
               VerticalAlignment="Bottom" 
               Width="16" Height="16" >
            <i:Interaction.Behaviors>
                <helpers:PopupResizeBehaviors PopupObject="{Binding ElementName=Popbox}"/>
            </i:Interaction.Behaviors>
        </Thumb>
    </Grid>
</Popup>


class PopupResizeBehaviors : Behavior<Thumb>
{
    private bool mouseDown;
    private Point oldMousePosition;

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.PreviewMouseLeftButtonDown += (s, e) =>
        {
            mouseDown = true;
        };

        AssociatedObject.DragDelta += (s, e) =>
        {
            if (!mouseDown) return;

            double tempWidth = 0;
            double tempHeight = 0;
            PopupObject.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            tempWidth = PopupObject.DesiredSize.Width;
            tempHeight = PopupObject.DesiredSize.Height;

            double yadjust = tempHeight + e.VerticalChange;
            double xadjust = tempWidth + e.HorizontalChange;

            PopupObject.Width = xadjust;
            PopupObject.Height = yadjust;
        };

        AssociatedObject.PreviewMouseLeftButtonUp += (s, e) =>
        {
            mouseDown = false;
        };
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
    }

    public static readonly DependencyProperty PopupObjectProperty =
        DependencyProperty.RegisterAttached("PopupObject", typeof(Popup), typeof(PopupResizeBehaviors), new UIPropertyMetadata(null));

    public Popup PopupObject
    {
        get { return (Popup)GetValue(PopupObjectProperty); }
        set { SetValue(PopupObjectProperty, value); }
    }
}

It is not currently working but should give a good idea of what I'm aiming for.

How to get this behavior to work?


Solution

  • This is what I used in the end.

    class PopupResizeBehaviors : Behavior<Thumb>
    {
        private const int MaxSize = 500;
        private const int MinSize = 50;
    
        protected override void OnAttached()
        {
            base.OnAttached();
    
            AssociatedObject.DragDelta += (s, e) =>
            {
    
                Thumb t = s as Thumb;
    
                if (t.Cursor == Cursors.SizeWE || t.Cursor == Cursors.SizeNWSE)
                {
                    PopupObject.Width = Math.Min(MaxSize,
                      Math.Max(PopupObject.Width + e.HorizontalChange,
                      MinSize));
                }
    
                if (t.Cursor == Cursors.SizeNS || t.Cursor == Cursors.SizeNWSE)
                {
                    PopupObject.Height = Math.Min(MaxSize,
                      Math.Max(PopupObject.Height + e.VerticalChange,
                      MinSize));
                }
            };
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
        }
    
        public static readonly DependencyProperty PopupObjectProperty =
            DependencyProperty.RegisterAttached("PopupObject", typeof(Popup), typeof(PopupResizeBehaviors), new UIPropertyMetadata(null));
    
        public Popup PopupObject
        {
            get { return (Popup)GetValue(PopupObjectProperty); }
            set { SetValue(PopupObjectProperty, value); }
        }
    }