在WPF中实现区域拖动

在WPF中实现区域拖动的思路主要是,对鼠标按下、弹起、移动事件进行处理:鼠标按下时标记为可以移动并记录初始位置信息,鼠标弹起时标记不可以移动,鼠标移动过程中如果界面元素可以移动就动态设置相关位置。具体而言,需要处理的事件为:PreviewMouseLeftButtonDown、PreviewMouseLeftButtonUp、PreviewMouseMove。

本文的拖动环境是Grid,因此思路是:界面元素处鼠标按下时记录UI元素的Margin和鼠标在UI元素父对象的位置;鼠标移动过程中,如果可以移动,获取鼠标在UI元素父对象的新位置,通过和初始位置进行比较,获取并设置UI元素新的Margin,实现UI元素的移动。

UI布局:

<Grid x:Name="GridMain">
    <wpf:ChromiumWebBrowser x:Name="Browser" RenderOptions.BitmapScalingMode="HighQuality"/>
    <Grid x:Name="GridWidget" Width="40" Height="80" Opacity="0.8"
          HorizontalAlignment="Left" VerticalAlignment="Top"
          PreviewMouseLeftButtonDown="UIElement_OnMouseLeftButtonDown"
          PreviewMouseLeftButtonUp="UIElement_OnMouseLeftButtonUp"
          PreviewMouseMove="UIElement_OnMouseMove">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Width="40" Height="40" Padding="-10" ToolTip="刷新"
                Click="ButtonBase_OnClick">
            <TextBlock Style="{StaticResource IconFontStyle}" Text="&#xec08;" FontSize="26"/>
        </Button>
        <Button Grid.Row="1" Width="40" Height="40" ToolTip="移动" Padding="-10">
            <TextBlock Style="{StaticResource IconFontStyle}" Text="&#xe64d;" FontSize="26"/>
        </Button>
    </Grid>
</Grid>

后台代码:

private bool _enableMove;
private Thickness _margin;
private Point _position;

private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    _enableMove = true;
    _position = e.GetPosition(GridMain);
    _margin = GridWidget.Margin;
}

private void UIElement_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    _enableMove = false;
}

private void UIElement_OnMouseMove(object sender, MouseEventArgs e)
{
    if (!_enableMove)
    {
        return;
    }

    var position = e.GetPosition(GridMain);
    var left = _margin.Left + (position.X - _position.X);
    var top = _margin.Top + (position.Y - _position.Y);
    left = Math.Max(left, 0);
    top = Math.Max(top, 0);
    GridWidget.Margin = new Thickness(left, top, _margin.Right, _margin.Bottom);
}

程序效果:

 

posted @ 2022-11-04 15:26  xhubobo  阅读(613)  评论(0编辑  收藏  举报