使用鼠标拖动边缘可调整拇指控件的大小

问题描述 投票:14回答:1

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

如何实现?

c# wpf wpf-controls
1个回答
23
投票
基于ContentControl,因此您可以在其中添加任何Element并在Canvas上移动/调整大小,它使用3 Adorners,一个用于调整大小,一个用于移动,一个用于显示信息(当前大小)

如果您要测试/使用/修改/改进,这里是一个完整的工作示例:]

代码:

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; } } }

Xaml:

<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>

结果:

“在这里输入的图像描述” “在此处输入图片描述”

带有内容(按钮内)

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9hMFZDbC5wbmcifQ==” alt =“在此处输入图像描述”>

对不起,使用SnipTool时光标不显示

© www.soinside.com 2019 - 2024. All rights reserved.