Make a Thumb control sizable using the mouse to drag an edge

前端 未结 1 2060
借酒劲吻你
借酒劲吻你 2021-01-30 15:24

I need a thumb control that can be sized using a mouse. When the user hovers the mouse over one of the ends a size cursor should be displayed and when the user clicks and drags

1条回答
  •  耶瑟儿~
    2021-01-30 15:57

    Here is one I made a while ago, it allows Move and Resize, but you can remove the Move logic and it should work fine (the style is still a bit messy, but it works pretty well)

    Its based on ContentControl so you can add any Element inside and Move/Resize on a Canvas, It uses 3 Adorners, one for Resize, one for Move and one to display information (current size)

    Here is a full working example if you want to test/use/modify/improve :)

    Code:

    namespace WpfApplication21
    {
        /// 
        /// Interaction logic for MainWindow.xaml
        /// 
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        public class ResizeThumb : Thumb
        {
            public ResizeThumb()
            {
                DragDelta += new DragDeltaEventHandler(this.ResizeThumb_DragDelta);
            }
    
            private void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
            {
                Control designerItem = this.DataContext as Control;
    
                if (designerItem != null)
                {
                    double deltaVertical, deltaHorizontal;
    
                    switch (VerticalAlignment)
                    {
                        case VerticalAlignment.Bottom:
                            deltaVertical = Math.Min(-e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight);
                            designerItem.Height -= deltaVertical;
                            break;
                        case VerticalAlignment.Top:
                            deltaVertical = Math.Min(e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight);
                            Canvas.SetTop(designerItem, Canvas.GetTop(designerItem) + deltaVertical);
                            designerItem.Height -= deltaVertical;
                            break;
                        default:
                            break;
                    }
    
                    switch (HorizontalAlignment)
                    {
                        case HorizontalAlignment.Left:
                            deltaHorizontal = Math.Min(e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth);
                            Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem) + deltaHorizontal);
                            designerItem.Width -= deltaHorizontal;
                            break;
                        case HorizontalAlignment.Right:
                            deltaHorizontal = Math.Min(-e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth);
                            designerItem.Width -= deltaHorizontal;
                            break;
                        default:
                            break;
                    }
                }
    
                e.Handled = true;
            }
        }
    
    
        public class MoveThumb : Thumb
        {
            public MoveThumb()
            {
                DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta);
            }
    
            private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
            {
                Control designerItem = this.DataContext as Control;
    
                if (designerItem != null)
                {
                    double left = Canvas.GetLeft(designerItem);
                    double top = Canvas.GetTop(designerItem);
    
                    Canvas.SetLeft(designerItem, left + e.HorizontalChange);
                    Canvas.SetTop(designerItem, top + e.VerticalChange);
                }
            }
        }
    
        public class SizeAdorner : Adorner
        {
            private Control chrome;
            private VisualCollection visuals;
            private ContentControl designerItem;
    
            protected override int VisualChildrenCount
            {
                get
                {
                    return this.visuals.Count;
                }
            }
    
            public SizeAdorner(ContentControl designerItem)
                : base(designerItem)
            {
                this.SnapsToDevicePixels = true;
                this.designerItem = designerItem;
                this.chrome = new Control();
                this.chrome.DataContext = designerItem;
                this.visuals = new VisualCollection(this);
                this.visuals.Add(this.chrome);
            }
    
            protected override Visual GetVisualChild(int index)
            {
                return this.visuals[index];
            }
    
            protected override Size ArrangeOverride(Size arrangeBounds)
            {
                this.chrome.Arrange(new Rect(new Point(0.0, 0.0), arrangeBounds));
                return arrangeBounds;
            }
        }
    }
    

    Xaml:

    
    
        
    
            
                                    
                                
                                
                                    
                                        
                                                                
                                                                
                                                                
                                                                
                                                                
                                                                
                                                            
                                                        
                                                    
                                                
                                            
                                        
                                    
                                
                                
                                    
                                    
                                    
                                    
                                        
                                            
                                        
                                    
                                
                                
                            
                            
                                
                                    
                                
                                
                                    
                                
                            
                        
                    
                
            
    
        
    
        
            
        
    
    

    Result:

    enter image description here enter image description here

    With content inside (Button)

    enter image description here

    Sorry the cursors do not show when using SnipTool

    0 讨论(0)
提交回复
热议问题