C# 使用鼠标拖动一条边,使拇指控件大小可调

C# 使用鼠标拖动一条边,使拇指控件大小可调,c#,wpf,wpf-controls,C#,Wpf,Wpf Controls,我需要一个拇指控制,可以使用鼠标大小。当用户将鼠标悬停在一端时,应显示一个大小光标,当用户单击并拖动控件的一端时,将重新调整大小 如何实现这一点?这是我不久前做的一个,它允许移动和调整大小,但您可以删除移动逻辑,它应该可以正常工作(样式仍然有点凌乱,但效果相当不错) 它基于ContentControl,因此您可以在画布上添加任何元素并移动/调整大小,它使用3个装饰器,一个用于调整大小,一个用于移动,一个用于显示信息(当前大小) 如果您想测试/使用/修改/改进,下面是一个完整的工作示例:) 代码:

我需要一个拇指控制,可以使用鼠标大小。当用户将鼠标悬停在一端时,应显示一个大小光标,当用户单击并拖动控件的一端时,将重新调整大小


如何实现这一点?

这是我不久前做的一个,它允许
移动
调整大小
,但您可以删除
移动
逻辑,它应该可以正常工作(样式仍然有点凌乱,但效果相当不错)

它基于
ContentControl
,因此您可以在
画布上添加任何
元素并移动/调整大小,它使用3个
装饰器,一个用于调整大小,一个用于移动,一个用于显示信息(当前大小)

如果您想测试/使用/修改/改进,下面是一个完整的工作示例:)

代码:

名称空间WpfApplication21
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
}
公共类ResizeThumb:Thumb
{
公众辞职
{
DragDelta+=新的DragDeltaEventHandler(this.resizetumb_DragDelta);
}
私有void resizetumb_DragDelta(对象发送方,DragDeltaEventArgs e)
{
Control designerItem=this.DataContext作为控件;
如果(designerItem!=null)
{
双三角洲垂直,三角洲水平;
开关(垂直对齐)
{
外壳垂直对齐。底部:
deltaVertical=数学最小值(-e.垂直变化,designerItem.ActualHeight-designerItem.MinHeight);
设计项目高度-=三角高程;
打破
外壳垂直对齐。顶部:
deltaVertical=Math.Min(例如垂直变化、designerItem.ActualHeight-designerItem.MinHeight);
Canvas.SetTop(designerItem,Canvas.GetTop(designerItem)+deltaVertical);
设计项目高度-=三角高程;
打破
违约:
打破
}
开关(水平对齐)
{
案例水平对齐。左:
deltaHorizontal=Math.Min(例如水平变化、designerItem.ActualWidth-designerItem.MinWidth);
Canvas.SetLeft(designerItem,Canvas.GetLeft(designerItem)+deltaHorizontal);
设计项目宽度-=水平三角形;
打破
案例水平对齐。右侧:
deltaHorizontal=数学.Min(-e.水平变化,designerItem.ActualWidth-designerItem.MinWidth);
设计项目宽度-=水平三角形;
打破
违约:
打破
}
}
e、 已处理=正确;
}
}
公共类MoveThumb:Thumb
{
公共运动
{
DragDelta+=新的DragDeltaEventHandler(this.MoveThumb_DragDelta);
}
私有void MoveThumb_DragDelta(对象发送方,DragDeltaEventArgs e)
{
Control designerItem=this.DataContext作为控件;
如果(designerItem!=null)
{
左双=Canvas.GetLeft(designerItem);
double-top=Canvas.GetTop(designerItem);
Canvas.SetLeft(designerItem,left+e.HorizontalChange);
Canvas.SetTop(designerItem,top+e.VerticalChange);
}
}
}
公共类SizedOrner:装饰器
{
私人控制;
私人视频采集视频;
私有内容控制设计项;
受保护的重写int VisualChildrenCount
{
得到
{
返回此.visuals.Count;
}
}
公共SizedOrner(ContentControl designerItem)
:基础(设计元素)
{
this.SnapsToDevicePixels=true;
this.designerItem=designerItem;
this.chrome=新控件();
this.chrome.DataContext=designerItem;
this.visuals=新的VisualCollection(this);
this.visuals.Add(this.chrome);
}
受保护的重写Visual GetVisualChild(int索引)
{
返回此.visuals[索引];
}
受保护的替代尺寸ArrangeOverride(尺寸arrangeBounds)
{
this.chrome.Arrange(新Rect(新点(0.0,0.0),arrangeBounds));
返回安排边界;
}
}
}
Xaml:


namespace WpfApplication21
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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;
        }
    }
}
<Window x:Class="WpfApplication21.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication21"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ContentControl}">
                        <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                            <local:MoveThumb Cursor="SizeAll">
                                <local:MoveThumb.Style>
                                    <Style TargetType="{x:Type local:MoveThumb}">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type local:MoveThumb}">
                                                    <Rectangle Fill="Transparent" />
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </local:MoveThumb.Style>
                            </local:MoveThumb>
                            <Control x:Name="resizer">
                                <Control.Style>
                                    <Style TargetType="{x:Type Control}">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type Control}">
                                                    <Grid>
                                                        <Grid Opacity="0" Margin="-3">
                                                            <local:ResizeThumb Height="3" Cursor="SizeNS" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
                                                            <local:ResizeThumb Width="3" Cursor="SizeWE" VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
                                                            <local:ResizeThumb Width="3" Cursor="SizeWE" VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
                                                            <local:ResizeThumb Height="3" Cursor="SizeNS" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
                                                            <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNWSE" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                                                            <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNESW" VerticalAlignment="Top" HorizontalAlignment="Right"/>
                                                            <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNESW" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
                                                            <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNWSE" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
                                                        </Grid>
                                                        <Grid IsHitTestVisible="False" Opacity="1" Margin="-3">
                                                            <Grid.Resources>
                                                                <Style TargetType="{x:Type Ellipse}">
                                                                    <Setter Property="SnapsToDevicePixels" Value="true" />
                                                                    <Setter Property="Stroke" Value="#FFC8C8C8" />
                                                                    <Setter Property="StrokeThickness" Value=".5" />
                                                                    <Setter Property="Width" Value="7" />
                                                                    <Setter Property="Height" Value="7" />
                                                                    <Setter Property="Margin" Value="-2" />
                                                                    <Setter Property="Fill" Value="Silver" />
                                                                </Style>
                                                            </Grid.Resources>
                                                            <Rectangle SnapsToDevicePixels="True" StrokeThickness="1" Margin="1" Stroke="Black"  StrokeDashArray="4 4"/>
                                                            <Ellipse  HorizontalAlignment="Left" VerticalAlignment="Top"/>
                                                            <Ellipse  HorizontalAlignment="Right" VerticalAlignment="Top"/>
                                                            <Ellipse HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
                                                            <Ellipse  HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                                        </Grid>
                                                    </Grid>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </Control.Style>
                            </Control>
                            <Grid x:Name="sizeInfo" SnapsToDevicePixels="True">
                                <Path Stroke="Red" StrokeThickness="1" Height="10" VerticalAlignment="Bottom" Margin="-2,0,-2,-15" Stretch="Fill" Data="M0,0 0,10 M 0,5 100,5 M 100,0 100,10"/>
                                <TextBlock Text="{Binding Width}" Background="White" Padding="3,0,3,0" Foreground="Red" Margin="0,0,0,-18" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
                                <Path Stroke="Red" StrokeThickness="1" Width="10" HorizontalAlignment="Right" Margin="0,-2,-15,-2" Stretch="Fill" Data="M5,0 5,100 M 0,0 10,0 M 0,100 10,100"/>
                                <TextBlock Text="{Binding Height}" Background="White" Foreground="Red" Padding="3,0,3,0" Margin="0,0,-18,0" HorizontalAlignment="Right" VerticalAlignment="Center">
                                    <TextBlock.LayoutTransform>
                                        <RotateTransform Angle="90" CenterX="1" CenterY="0.5"/>
                                    </TextBlock.LayoutTransform>
                                </TextBlock>
                            </Grid>
                            <ContentPresenter Content="{TemplateBinding Content}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger  Property="IsMouseOver" Value="True">
                                <Setter TargetName="sizeInfo" Property="Visibility" Value="Visible" />
                            </Trigger>
                            <Trigger  Property="IsMouseOver" Value="False">
                                <Setter TargetName="sizeInfo" Property="Visibility" Value="Hidden" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>

    <Canvas>
        <ContentControl Width="183" Height="110"  Canvas.Left="166" Canvas.Top="50" />
    </Canvas>
</Window>