• UWP 用Thumb 控件仿制一个可拖动悬浮 Button


    参考了 http://www.cnblogs.com/zhanggaoxing/p/6403430.html,并加以改进。

     最终效果:::

    Thumb 的原生事件 DragStarted,DragDelta,DragCompleted。
    DragStarted 和字面意思差不多,开始拖动的时候发生的。
    DragDelta 拖动进行中,只要你鼠标不放就会一直进行。
    DragCompleted 拖动结束后发生。

     首先需要在合适的页面敲上一个 <Thumb />,给它个 Name="RootThumb",我是把它放在页面右下角的。

    <Thumb x:Name="RootThumb" Width="50" Height="50" Margin="0,0,50,50" HorizontalAlignment="Right" VerticalAlignment="Bottom" Canvas.ZIndex="101" Tapped="RootThumb_Tapped" DragDelta="RootThumb_DragDelta">
    </Thumb>

    这时设计器右下角应该出现了一个方块,但它不是我需要的圆形,下面打开 Blend 进行样式定制.

     

    点击编辑后,加载了默认的 Thumb 样式。
    替换Style,

    <Style x:Key="ThumbStyle1" TargetType="Thumb">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="BorderBrush" Value="{ThemeResource ThumbBorderBrush}"/>
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="Thumb">
    <Grid x:Name="RootGrid">
    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
    <VisualState x:Name="Normal"/>
    <VisualState x:Name="PointerOver">
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPointerOver"/>
    <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Pressed">
    <Storyboard>
    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPressed"/>
    <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Disabled"/>
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Rectangle RadiusY="25" RadiusX="25" Fill="Gray" Opacity="0.6" Stroke="{ThemeResource SystemControlBackgroundAccentBrush}" StrokeThickness="3" />
    <TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE710;" FontSize="22" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" />
    <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
    <Border x:Name="BackgroundPointerOver" BorderBrush="{ThemeResource ThumbBorderBrushPointerOver}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Opacity="0"/>
    <Border x:Name="BackgroundPressed" BorderBrush="{ThemeResource ThumbBorderBrushPressed}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Opacity="0"/>
    </Grid>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    定制好的样式就粗来啦,那个周边颜色根据系统色而改变的

     

    Button 的 Click 事件怎么实现呢?有 PointerPressed 和 Tapped 两个备选事件。现在的交互事件有三种:Mouse Events(鼠标事件),Touch Events(触摸事件)和 Pointer Events(指针事件),分别为不同的设备提供不同的交互方式。说这么多废话其实直接试试就好了。。。在 Thumb 的 xml 标记里添加 Tapped="RootThumb_Tapped",事件代码如下

    private async void RootThumb_Tapped(object sender, TappedRoutedEventArgs e)
    {
    ContentDialog cd = new ContentDialog
    {
    Title = "消息提示",
    PrimaryButtonText = "确定",
    SecondaryButtonText = "取消",
    Content = "当前设置尚未保存,你确认要退出该页面吗?",
    };
    
    cd.PrimaryButtonClick += Cd_PrimaryButtonClick;
    await cd.ShowAsync();
    }

    下面说说拖动怎么实现,需要编写 DragDelta 事件。由于 Win10 设备体系庞大,UWP 上谈控件坐标没啥意义,这也正是 WPF 上的控件拖动方案没用的原因。如果你在设计器里像 WinForm 一样拖拽控件设计布局的话,xaml 会给被拖拽的控件一个 Margin,因此 Thumb 的拖拽实现也用的 Margin。首先你需要定义两个 double 私有字段记录 X, Y 轴的位移量。设计目的是 Thumb 在右下角,而页面的坐标零点在左上角,只需要将 Thumb 的 Margin 的 Right,Bottom 给一个位移量的负值即可。完整代码如下。

    private double thumbX = -50, thumbY = -50;
    
    private void RootThumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
    // 两个 double 类型,用来记录偏移量
    thumbX += e.HorizontalChange;
    thumbY += e.VerticalChange;
    
    if (-thumbX < 0 && -thumbY < 0)
    {
    RootThumb.Margin = new Thickness(0, 0, 0, 0);
    thumbX = 0; thumbY = 0;
    }
    else if (-thumbX < 0)
    {
    RootThumb.Margin = new Thickness(0, 0, 0, -thumbY);
    thumbX = 0;
    }
    else if (-thumbY < 0)
    {
    RootThumb.Margin = new Thickness(0, 0, -thumbX, 0);
    thumbY = 0;
    }
    else if (-thumbX > (Window.Current.Bounds.Width - RootThumb.Width) && -thumbY > (Window.Current.Bounds.Height - RootThumb.Height))
    {
    thumbX = -(Window.Current.Bounds.Width - RootThumb.Width);
    thumbY = -(Window.Current.Bounds.Height - RootThumb.Height);
    RootThumb.Margin = new Thickness(0, 0, Window.Current.Bounds.Width - RootThumb.Width, Window.Current.Bounds.Height - RootThumb.Height);
    }
    else if(-thumbX > (Window.Current.Bounds.Width - RootThumb.Width))
    {
    thumbX = -(Window.Current.Bounds.Width - RootThumb.Width);
    RootThumb.Margin = new Thickness(0, 0, Window.Current.Bounds.Width - RootThumb.Width, -thumbY);
    }
    else if (-thumbY > (Window.Current.Bounds.Height - RootThumb.Height))
    {
    thumbY = -(Window.Current.Bounds.Height - RootThumb.Height);
    RootThumb.Margin = new Thickness(0, 0, -thumbX, Window.Current.Bounds.Height - RootThumb.Height);
    }
    else
    {
    RootThumb.Margin = new Thickness(0, 0, -thumbX, -thumbY);
    }
    }

    上述代码完成了,但是有个问题,就是窗口从大变小之后,浮动按钮还是按照原来的margin,所以会消失。我这里直接给了一个固定的值,就不消失了。

    private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
    {
    //防止窗体改变大小后消失
    RootThumb.Margin = new Thickness(0, 0, 50, 50);
    thumbX = -50; thumbY = -50;
    }
  • 相关阅读:
    springMVC 使用WebApplicationContext获取ApplicationContext对象
    idea for mac 最全快捷键整理
    装饰模式 应用场景和实现
    RabbitMQ基础知识详解
    jetty 介绍以及小例子
    业务对象的贫血模型与充血模型
    同构与异构
    Java设计模式之策略模式与状态模式
    C++之内部类(嵌套类)与外部类及友元
    深入理解Java中为什么内部类可以访问外部类的成员
  • 原文地址:https://www.cnblogs.com/hupo376787/p/7620273.html
Copyright © 2020-2023  润新知