WPF 用装饰器制作抽屉效果

发布时间:2024-11-24 22:50

利用抽屉分隔器,提高抽屉收纳效率 #生活技巧# #收纳整理技巧# #家庭杂物储藏室#

最新推荐文章于 2024-10-14 02:17:54 发布

dotNET跨平台 于 2021-05-11 08:00:00 发布

wpf实现抽屉效果,一般就一个动画显示就完事了,我这用到了,就研究了一下,用装饰器给控件添加遮罩层,然后在上面添加抽屉控件,虽然麻烦了点,也算是自己研究的成果了。

看看效果:

下面就看看代码:

首先是新建一个装饰器类,和之前用过的文章:WPF 使用装饰器给控件添加遮罩层 中用的是同样的,

public class SimpleAdorner : Adorner

{

private UIElement child;

public SimpleAdorner(UIElement adornedElement) : base(adornedElement)

{

}

public UIElement Child

{

get => child;

set

{

if (value == null)

{

RemoveVisualChild(child);

}

else

{

AddVisualChild(value);

}

child = value;

}

}

protected override int VisualChildrenCount => 1;

protected override Size ArrangeOverride(Size finalSize)

{

child?.Arrange(new Rect(finalSize));

return finalSize;

}

protected override Visual GetVisualChild(int index)

{

if (index == 0 && child != null) return child;

return base.GetVisualChild(index);

}

}

然后新建一个类:

[TemplatePart(Name = DrawerGrid,Type =typeof(Grid))]

[TemplatePart(Name = CloseButton,Type =typeof(Button))]

public class GDrawer : ContentControl

{

public Action Closed;

private const string DrawerGrid = "DrawerGrid";

private const string CloseButton = "CloseButton";

private Grid _drawerGrid;

private Button _closeButton;

public override void OnApplyTemplate()

{

base.OnApplyTemplate();

_drawerGrid = GetTemplateChild(DrawerGrid) as Grid;

_closeButton = GetTemplateChild(CloseButton) as Button;

_closeButton.Click += (s, e) => IsOpen = false;

Loaded += OnLoaded;

}

private void OnLoaded(object sender, RoutedEventArgs e)

{

IsOpen = true;

}

public bool IsOpen

{

get { return (bool)GetValue(IsOpenProperty); }

set { SetValue(IsOpenProperty, value); }

}

public static readonly DependencyProperty IsOpenProperty =

DependencyProperty.Register("IsOpen", typeof(bool), typeof(GDrawer), new PropertyMetadata(false,(s,e)=> {

var drawer = s as GDrawer;

if(e.NewValue is bool b && b)

{

drawer.StartAnimationIn();

}

else

{

drawer.StartAnimationOut();

}

}));

private async void StartAnimationIn(float seconds=0.3f)

{

var sb = new Storyboard();

var offset = _drawerGrid.ActualWidth;

var animation = new ThicknessAnimation

{

Duration = new Duration(TimeSpan.FromSeconds(seconds)),

From = new Thickness(-offset,0 , offset,0 ),

To = new Thickness(0)

};

Storyboard.SetTargetProperty(animation, new PropertyPath("Margin"));

sb.Children.Add(animation);

sb.Begin(_drawerGrid);

await Task.Delay((int)(seconds * 1000));

}

private async void StartAnimationOut(float seconds=0.3f)

{

var sb = new Storyboard();

var offset = _drawerGrid.ActualWidth;

var animation = new ThicknessAnimation

{

Duration = new Duration(TimeSpan.FromSeconds(seconds)),

From = new Thickness(0),

To = new Thickness(-offset, 0, offset, 0),

};

Storyboard.SetTargetProperty(animation, new PropertyPath("Margin"));

sb.Children.Add(animation);

sb.Begin(_drawerGrid);

await Task.Delay((int)(seconds * 1000));

Closed?.Invoke();

}

}

这个就是抽屉效果的实现类了,

然后,在App.xaml里添加样式和资源 :

<Style TargetType="local:GDrawer">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="local:GDrawer">

<Grid x:Name="DrawerGrid"

MinWidth="300" MinHeight="100"

HorizontalAlignment="Left"

VerticalAlignment="Stretch"

Background="White">

<Button x:Name="CloseButton" Margin="10" Width="50" Height="30" HorizontalAlignment="Right" VerticalAlignment="Top">关闭</Button>

<ContentPresenter />

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

<local:GDrawer x:Key="LeftDrawer">

<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" Foreground="Red">这是内容</TextBlock>

</local:GDrawer>

最后,来到MainWindow窗口,xaml代码如下:

<Window x:Class="WPFDemos.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:local="clr-namespace:WPFDemos"

mc:Ignorable="d"

x:Name="widnow"

WindowStartupLocation="CenterScreen"

Title="title" Height="500" Width="1000">

<Grid x:Name="grid" Background="LightBlue">

<AdornerDecorator/>

<Button Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center">打开</Button>

</Grid>

</Window>

MainWindow窗体后台代码:

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

}

private void Button_Click(object sender, RoutedEventArgs e)

{

ShowModal(grid);

}

SimpleAdorner _adorner = null;

public void ShowModal(Visual visual)

{

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);

var drawer = FindResource("LeftDrawer") as GDrawer;

drawer.Closed = () => adornerLayer.Remove(_adorner);

_adorner = _adorner?? new SimpleAdorner(adornerLayer)

{

Child = new Border()

{

Background = new SolidColorBrush(Color.FromArgb(150, 0, 0, 0)),

Child = drawer

}

};

adornerLayer.Add(_adorner);

}

}

这样就完成了,

如果喜欢,点个赞呗~

网址:WPF 用装饰器制作抽屉效果 https://www.yuejiaxmz.com/news/view/244767

相关内容

一种抽屉分隔器的制作方法
如何在15分钟内制作自制抽屉分隔器
环保抽屉匣的制作方法
抽屉可以装反弹器吗
抽屉组件的制作方法
抽屉控制器 (Drawer Controller)
【抽屉整理器餐具】
抽屉整理器.pdf
西曼帝克抽屉内饰
手把手教你制作抽屉式收纳柜

随便看看