亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

WPF實(shí)現(xiàn)Drawer抽屜控件

 更新時(shí)間:2024年11月08日 11:31:41   作者:WPF開(kāi)發(fā)者  
這篇文章主要為大家詳細(xì)介紹了如何使用WPF實(shí)現(xiàn)一個(gè)Drawer抽屜控件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

Drawer 抽屜控件的實(shí)現(xiàn)

框架支持.NET4 至 .NET8

Visual Studio 2022;

抽屜控件的邏輯實(shí)現(xiàn)

定義了一個(gè)名為 Drawer 的自定義控件,繼承自 HeaderedContentControl,允許用戶在應(yīng)用程序中創(chuàng)建可展開(kāi)和收起的抽屜。抽屜的顯示和隱藏動(dòng)畫(huà)通過(guò) Storyboard 實(shí)現(xiàn),支持從不同方向(、、)展開(kāi)和收起。

1.定義模板

使用 TemplatePart 特性定義了兩個(gè)模板:BorderHeaderTemplateName 和 BorderMarkTemplateName,分別代表抽屜的蒙板部分。

[TemplatePart(Name = BorderHeaderTemplateName, Type = typeof(Border))]
[TemplatePart(Name = BorderMarkTemplateName, Type = typeof(Border))]
public class Drawer : HeaderedContentControl

2.定義依賴屬性

  • Position 抽屜展開(kāi)的方向(、、)。
  • IsOpen 抽屜是否打開(kāi),狀態(tài)變化時(shí)調(diào)用 OnIsOpenChanged 方法。
public static readonly DependencyProperty EdgePositionProperty =
    DependencyProperty.Register("Position", typeof(Position), typeof(Drawer),
        new PropertyMetadata(Position.Left));

public static readonly DependencyProperty IsOpenProperty =
    DependencyProperty.Register("IsOpen", typeof(bool), typeof(Drawer),
        new PropertyMetadata(false, OnIsOpenChanged));

3.屬性實(shí)現(xiàn)

public Position Position
{
    get => (Position) GetValue(EdgePositionProperty);
    set => SetValue(EdgePositionProperty, value);
}

public bool IsOpen
{
    get => (bool) GetValue(IsOpenProperty);
    set => SetValue(IsOpenProperty, value);
}

4.狀態(tài)變化處理

OnIsOpenChanged 方法根據(jù) IsOpen 屬性的值,控制抽屜的顯示或隱藏和動(dòng)畫(huà)效果。

private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var ctrl = d as Drawer;
    if (ctrl != null)
    {
        if (ctrl.IsOpen)
        {
            ctrl._headerBorder.Visibility = Visibility.Visible;
            ctrl._enterStoryboard.Begin();
        }
        else
        {
            ctrl._exitStoryboard.Begin();
        }
    }
}

5.模板應(yīng)用

OnApplyTemplate 方法在控件模板應(yīng)用時(shí)調(diào)用,獲取模板中的 Border 部件并注冊(cè) Loaded 和 MouseDown 事件。

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    _headerBorder = GetTemplateChild(BorderHeaderTemplateName) as Border;
    if (_headerBorder != null)
        _headerBorder.Loaded += HeaderBorder_Loaded;
    _markBorder = GetTemplateChild(BorderMarkTemplateName) as Border;
    if (_markBorder != null)
        _markBorder.MouseDown += MarkBorder_MouseDown;
}

6.動(dòng)畫(huà)實(shí)現(xiàn)

HeaderBorder_Loaded 方法根據(jù) Position 的不同,設(shè)置不同的動(dòng)畫(huà),并根據(jù)屬性值控制動(dòng)畫(huà)的執(zhí)行。

        private void HeaderBorder_Loaded(object sender, RoutedEventArgs e)
        {
            TranslateTransform translateTransform;
            DoubleAnimation animation, exitAnimation;
            switch (Position)
            {
                case Position.Left:
                case Position.Right:
                    _headerWidth = _headerBorder.ActualWidth;
                    if (Position == Position.Left)
                        translateTransform = new TranslateTransform(-_headerWidth, 0);
                    else
                        translateTransform = new TranslateTransform(_headerWidth, 0);
                    _headerBorder.RenderTransform = new TransformGroup
                    {
                        Children = new TransformCollection {translateTransform}
                    };
                    animation = new DoubleAnimation
                    {
                        From = Position == Position.Left ? -_headerWidth : _headerWidth,
                        To = 0,
                        Duration = TimeSpan.FromMilliseconds(300)
                    };

                    Storyboard.SetTarget(animation, _headerBorder);
                    Storyboard.SetTargetProperty(animation, new PropertyPath("RenderTransform.Children[0].X"));
                    _enterStoryboard = new Storyboard();
                    _enterStoryboard.Children.Add(animation);

                    exitAnimation = new DoubleAnimation
                    {
                        From = 0,
                        To = Position == Position.Left ? -_headerWidth : _headerWidth,
                        Duration = TimeSpan.FromMilliseconds(300)
                    };

                    Storyboard.SetTarget(exitAnimation, _headerBorder);
                    Storyboard.SetTargetProperty(exitAnimation, new PropertyPath("RenderTransform.Children[0].X"));
                    _exitStoryboard = new Storyboard();
                    _exitStoryboard.Completed += delegate
                    {
                        if (!IsOpen)
                            _headerBorder.Visibility = Visibility.Collapsed;
                    };
                    _exitStoryboard.Children.Add(exitAnimation);
                    break;
                case Position.Top:
                case Position.Bottom:
                    _headerHeight = _headerBorder.ActualHeight;
                    if (Position == Position.Top)
                        translateTransform = new TranslateTransform(0, -_headerHeight);
                    else
                        translateTransform = new TranslateTransform(0, _headerHeight);
                    _headerBorder.RenderTransform = new TransformGroup
                    {
                        Children = new TransformCollection {translateTransform}
                    };
                    animation = new DoubleAnimation
                    {
                        From = Position == Position.Top ? -_headerHeight : _headerHeight,
                        To = 0,
                        Duration = TimeSpan.FromMilliseconds(300)
                    };

                    Storyboard.SetTarget(animation, _headerBorder);
                    Storyboard.SetTargetProperty(animation, new PropertyPath("RenderTransform.Children[0].Y"));
                    _enterStoryboard = new Storyboard();
                    _enterStoryboard.Children.Add(animation);

                    exitAnimation = new DoubleAnimation
                    {
                        From = 0,
                        To = Position == Position.Top ? -_headerHeight : _headerHeight,
                        Duration = TimeSpan.FromMilliseconds(300)
                    };

                    Storyboard.SetTarget(exitAnimation, _headerBorder);
                    Storyboard.SetTargetProperty(exitAnimation, new PropertyPath("RenderTransform.Children[0].Y"));
                    _exitStoryboard = new Storyboard();
                    _exitStoryboard.Completed += delegate
                    {
                        if (!IsOpen)
                            _headerBorder.Visibility = Visibility.Collapsed;
                    };
                    _exitStoryboard.Children.Add(exitAnimation);
                    break;
            }

            _headerBorder.Visibility = Visibility.Collapsed;
            _headerBorder.Loaded -= HeaderBorder_Loaded;
        }

GitHub 源碼地址

Gitee 源碼地址

抽屜控件的樣式實(shí)現(xiàn)

Position 屬性的觸發(fā)器:根據(jù) Position 屬性的值(TopRight、Bottom),調(diào)整 PART_Header 的對(duì)齊方式。

IsOpen 屬性的觸發(fā)器:如果 IsOpen 為 False,將 PART_Mark 的可見(jiàn)性設(shè)置為 Collapsed,在抽屜關(guān)閉時(shí)隱藏。

<Style
    x:Key="WD.Drawer"
    BasedOn="{StaticResource WD.ControlBasicStyle}"
    TargetType="{x:Type controls:Drawer}">
    <Setter Property="Background" Value="{DynamicResource WD.BackgroundSolidColorBrush}" />
    <Setter Property="BorderBrush" Value="{DynamicResource WD.BaseSolidColorBrush}" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:Drawer}">
                <controls:WDBorder
                    x:Name="Border"
                    Margin="{TemplateBinding Margin}"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    CornerRadius="{Binding Path=(helpers:ElementHelper.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
                    SnapsToDevicePixels="True">
                    <controls:SmallPanel Clip="{Binding RelativeSource={RelativeSource AncestorType=controls:WDBorder}, Path=ContentClip}">
                        <Border x:Name="PART_Content">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </Border>
                        <Border
                            x:Name="PART_Mark"
                            Background="{DynamicResource WD.PrimaryTextSolidColorBrush}"
                            Opacity=".5" />
                        <Border
                            x:Name="PART_Header"
                            HorizontalAlignment="Left"
                            Background="{TemplateBinding Background}"
                            Effect="{StaticResource WD.NormalShadowDepth}">
                            <ContentPresenter Content="{TemplateBinding Header}" />
                        </Border>
                    </controls:SmallPanel>
                </controls:WDBorder>
                <ControlTemplate.Triggers>
                    <Trigger Property="Position" Value="Top">
                        <Setter TargetName="PART_Header" Property="HorizontalAlignment" Value="Stretch" />
                        <Setter TargetName="PART_Header" Property="VerticalAlignment" Value="Top" />
                    </Trigger>
                    <Trigger Property="Position" Value="Right">
                        <Setter TargetName="PART_Header" Property="HorizontalAlignment" Value="Right" />
                        <Setter TargetName="PART_Header" Property="VerticalAlignment" Value="Stretch" />
                    </Trigger>
                    <Trigger Property="Position" Value="Bottom">
                        <Setter TargetName="PART_Header" Property="HorizontalAlignment" Value="Stretch" />
                        <Setter TargetName="PART_Header" Property="VerticalAlignment" Value="Bottom" />
                    </Trigger>
                    <Trigger Property="IsOpen" Value="False">
                        <Setter TargetName="PART_Mark" Property="Visibility" Value="Collapsed" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

示例

示例引入 WPFDevelopers 的 Nuget

<UserControl
    x:Class="WPFDevelopers.Samples.ExampleViews.DrawerExample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <controls:CodeViewer>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <wd:Drawer
                x:Name="MyDrawerTop"
                Margin="2"
                Position="Top">
                <wd:Drawer.Header>
                    <Grid Height="120">
                        <StackPanel HorizontalAlignment="Center">
                            <TextBlock FontSize="18" Text="Drawer" />
                            <Button HorizontalAlignment="Center" Content="contents..." />
                        </StackPanel>
                    </Grid>
                </wd:Drawer.Header>
                <wd:Drawer.Content>
                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom">
                        <TextBlock Text="抽屜從頂部置滑出,點(diǎn)擊遮罩區(qū)關(guān)閉。" />
                        <Button
                            Margin="0,10"
                            HorizontalAlignment="Center"
                            Click="ButtonTop_Click"
                            Content="Open"
                            Style="{StaticResource WD.PrimaryButton}" />
                    </StackPanel>
                </wd:Drawer.Content>
            </wd:Drawer>
            <wd:Drawer
                x:Name="MyDrawerBottom"
                Grid.Column="1"
                Margin="2"
                wd:ElementHelper.CornerRadius="3"
                Position="Bottom">
                <wd:Drawer.Header>
                    <Grid Height="130">
                        <StackPanel HorizontalAlignment="Center">
                            <TextBlock FontSize="18" Text="Drawer" />
                            <Button
                                HorizontalAlignment="Center"
                                wd:ElementHelper.CornerRadius="3"
                                Content="contents..."
                                Style="{StaticResource WD.DangerDefaultButton}" />
                        </StackPanel>
                    </Grid>
                </wd:Drawer.Header>
                <wd:Drawer.Content>
                    <StackPanel HorizontalAlignment="Center">
                        <TextBlock Text="抽屜從底部滑出,點(diǎn)擊遮罩區(qū)關(guān)閉。" />
                        <Button
                            Margin="0,10"
                            HorizontalAlignment="Center"
                            wd:ElementHelper.CornerRadius="3"
                            Click="ButtonBottom_Click"
                            Content="Open"
                            Style="{StaticResource WD.DangerPrimaryButton}" />
                    </StackPanel>
                </wd:Drawer.Content>
            </wd:Drawer>

            <wd:Drawer
                x:Name="MyDrawerLeft"
                Grid.Row="1"
                Margin="2"
                wd:ElementHelper.CornerRadius="3"
                Position="Left">
                <wd:Drawer.Header>
                    <Grid Width="140" Background="HotPink">
                        <StackPanel>
                            <TextBlock
                                HorizontalAlignment="Center"
                                FontSize="18"
                                Text="Drawer" />
                            <Button
                                HorizontalAlignment="Center"
                                wd:ElementHelper.CornerRadius="3"
                                Content="contents..."
                                Style="{StaticResource WD.SuccessDefaultButton}" />
                        </StackPanel>
                    </Grid>
                </wd:Drawer.Header>
                <wd:Drawer.Content>
                    <StackPanel HorizontalAlignment="Center">
                        <TextBlock Text="抽屜從左側(cè)滑出,點(diǎn)擊遮罩區(qū)關(guān)閉。" />
                        <Button
                            Margin="0,10"
                            HorizontalAlignment="Center"
                            wd:ElementHelper.CornerRadius="3"
                            Click="ButtonLeft_Click"
                            Content="Open"
                            Style="{StaticResource WD.SuccessPrimaryButton}" />
                    </StackPanel>
                </wd:Drawer.Content>
            </wd:Drawer>
            <wd:Drawer
                x:Name="MyDrawerRight"
                Grid.Row="1"
                Grid.Column="1"
                Margin="2"
                Position="Right">
                <wd:Drawer.Header>
                    <Grid Width="100">
                        <StackPanel HorizontalAlignment="Center">
                            <TextBlock
                                HorizontalAlignment="Center"
                                FontSize="18"
                                Text="Drawer" />
                            <Button
                                HorizontalAlignment="Center"
                                Content="contents..."
                                Style="{StaticResource WD.WarningDefaultButton}" />
                        </StackPanel>
                    </Grid>
                </wd:Drawer.Header>
                <wd:Drawer.Content>
                    <StackPanel HorizontalAlignment="Center">
                        <TextBlock Text="抽屜從右側(cè)滑出,點(diǎn)擊遮罩區(qū)關(guān)閉。" />
                        <Button
                            Margin="0,10"
                            HorizontalAlignment="Center"
                            Click="ButtonRight_Click"
                            Content="Open"
                            Style="{StaticResource WD.WarningPrimaryButton}" />
                    </StackPanel>
                </wd:Drawer.Content>
            </wd:Drawer>
        </Grid>
        <controls:CodeViewer.SourceCodes>
            <controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/DrawerExample.xaml" CodeType="Xaml" />
            <controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/DrawerExample.xaml.cs" CodeType="CSharp" />
        </controls:CodeViewer.SourceCodes>
    </controls:CodeViewer>
</UserControl>

效果圖

到此這篇關(guān)于WPF實(shí)現(xiàn)Drawer抽屜控件的文章就介紹到這了,更多相關(guān)WPF抽屜控件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論