生活随笔
收集整理的這篇文章主要介紹了
WPF 用装饰器制作抽屉效果
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
wpf實現(xiàn)抽屜效果,一般就一個動畫顯示就完事了,我這用到了,就研究了一下,用裝飾器給控件添加遮罩層,然后在上面添加抽屜控件,雖然麻煩了點,也算是自己研究的成果了。
看看效果:
下面就看看代碼:
首先是新建一個裝飾器類,和之前用過的文章:WPF 使用裝飾器給控件添加遮罩層?中用的是同樣的,
public class SimpleAdorner : Adorner{private UIElement child;public SimpleAdorner(UIElement adornedElement) : base(adornedElement){}//Adorner 直接繼承自 FrameworkElement,//沒有Content和Child屬性,//自己添加一個,方便向其中添加我們的控件public UIElement Child{get => child;set{if (value == null){RemoveVisualChild(child);}else{AddVisualChild(value);}child = value;}}//重寫VisualChildrenCount 表示此控件只有一個子控件protected override int VisualChildrenCount => 1;//控件計算大小的時候,我們在裝飾層上添加的控件也計算一下大小protected override Size ArrangeOverride(Size finalSize){child?.Arrange(new Rect(finalSize));return finalSize;}//重寫GetVisualChild,返回我們添加的控件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();}}
這個就是抽屜效果的實現(xiàn)類了,
然后,在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">關(guān)閉</Button><ContentPresenter /></Grid></ControlTemplate></Setter.Value></Setter>
</Style><local:GDrawer x:Key="LeftDrawer"><TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" Foreground="Red">這是內(nèi)容</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){//獲取visual上面的第一個AdornerLayerAdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);//創(chuàng)建我們定義的Adornervar 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);}}
這樣就完成了,
如果喜歡,點個贊唄~
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)
以上是生活随笔為你收集整理的WPF 用装饰器制作抽屉效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。