最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

框架支持.NET4 至 .NET8;

Visual Studio 2022;

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

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

1.定義模板

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

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

2.定義依賴屬性

  • Position 抽屜展開的方向(、、)。
  • IsOpen 抽屜是否打開,狀態(tài)變化時調(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.屬性實現(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 屬性的值,控制抽屜的顯示或隱藏和動畫效果。

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)用時調(diào)用,獲取模板中的 Border 部件并注冊 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.動畫實現(xiàn)

HeaderBorder_Loaded 方法根據(jù) Position 的不同,設(shè)置不同的動畫,并根據(jù)屬性值控制動畫的執(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 源碼地址

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

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

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

<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="抽屜從頂部置滑出,點擊遮罩區(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="抽屜從底部滑出,點擊遮罩區(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è)滑出,點擊遮罩區(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è)滑出,點擊遮罩區(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實現(xiàn)Drawer抽屜控件的文章就介紹到這了,更多相關(guān)WPF抽屜控件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中#define后面只加一個參數(shù)的解釋

    C#中#define后面只加一個參數(shù)的解釋

    今天小編就為大家分享一篇關(guān)于C#中#define后面只加一個參數(shù)的解釋,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • C#實現(xiàn)條形碼識別的解決方案分享

    C#實現(xiàn)條形碼識別的解決方案分享

    主流的識別庫主要有ZXing.NET和ZBar,OpenCV 4.0后加入了QR碼檢測和解碼功能,所以本文主要和大家分享了使用ZBar進(jìn)行條形碼識別的示例代碼,需要的可以參考一下
    2023-07-07
  • 淺析WPF中Popup彈出層的使用

    淺析WPF中Popup彈出層的使用

    這篇文章將通過一個簡單的小例子,為大家詳細(xì)介紹一下如何在WPF開發(fā)中,通過Popup實現(xiàn)鼠標(biāo)點擊彈出浮動停靠窗口,有需要的小伙伴可以了解下
    2024-01-01
  • C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個線程

    C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個線程

    本文主要介紹了C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 通過C#代碼輕松移除Word文檔中的文本與圖片水印

    通過C#代碼輕松移除Word文檔中的文本與圖片水印

    在日常工作和學(xué)習(xí)中,我們經(jīng)常會遇到帶有水印的Word文檔,它們有時會影響文檔的閱讀體驗,甚至在打印時造成不便,手動逐一刪除這些水印不僅效率低下,而且對于大量文檔來說更是一項艱巨的任務(wù),所以借助強(qiáng)大的C#編程,輕松實現(xiàn)Word文檔水印的批量移除
    2026-02-02
  • C#實現(xiàn)圖片縮略圖功能的示例詳解

    C#實現(xiàn)圖片縮略圖功能的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實現(xiàn)圖片縮略圖的功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#實現(xiàn)注冊碼的方法

    C#實現(xiàn)注冊碼的方法

    這篇文章主要介紹了C#實現(xiàn)注冊碼的方法,可實現(xiàn)C#生成軟件注冊碼的相關(guān)功能,涉及C#硬件操作及隨機(jī)數(shù)操作的相關(guān)技巧,非常具有實用價值,需要的朋友可以參考下
    2015-08-08
  • 改進(jìn)c# 代碼的五個技巧(二)

    改進(jìn)c# 代碼的五個技巧(二)

    這篇文章主要介紹了改進(jìn)c# 代碼的五個技巧(二),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • 在C#里面給PPT文檔添加注釋的實現(xiàn)代碼

    在C#里面給PPT文檔添加注釋的實現(xiàn)代碼

    平常開會或者做總結(jié)報告的時候我們通常都會用到PowerPoint演示文稿,我們可以在單個幻燈片或者全部幻燈片里面添加注釋,這樣觀眾可以從注釋內(nèi)容里面獲取更多的相關(guān)信息,需要的朋友可以參考下
    2017-01-01
  • c#?COM組件原理詳解

    c#?COM組件原理詳解

    本文主要介紹了c#?COM組件原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08

最新評論

景宁| 天门市| 扎兰屯市| 犍为县| 焉耆| 岫岩| 砚山县| 沙坪坝区| 甘孜| 临潭县| 南京市| 兰坪| 宜良县| 梨树县| 永清县| 全州县| 南靖县| 齐齐哈尔市| 柳河县| 南阳市| 柏乡县| 肥东县| 眉山市| 宽甸| 保亭| 嘉荫县| 阜阳市| 利川市| 武鸣县| 蒲城县| 敦煌市| 北宁市| 宿松县| 射阳县| 安庆市| 长垣县| 平湖市| 综艺| 墨脱县| 高邑县| 上思县|