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

c# WPF中自定義加載時(shí)實(shí)現(xiàn)帶動(dòng)畫(huà)效果的Form和FormItem

 更新時(shí)間:2021年03月05日 11:21:06   作者:Hello 尋夢(mèng)者!  
這篇文章主要介紹了c# WPF中自定義加載時(shí)實(shí)現(xiàn)帶動(dòng)畫(huà)效果的Form和FormItem,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下

背景

  今天我們來(lái)談一下我們自定義的一組WPF控件Form和FormItem,然后看一下如何自定義一組完整地組合WPF控件,在我們很多界面顯示的時(shí)候我們需要同時(shí)顯示文本、圖片并且我們需要將這些按照特定的順序整齊的排列在一起,這樣的操作當(dāng)然通過(guò)定義Grid和StackPanel然后組合在一起當(dāng)然也是可以的,我們的這一組控件就是將這個(gè)過(guò)程組合到一個(gè)Form和FormItem中間去,從而達(dá)到這樣的效果,我們首先來(lái)看看這組控件實(shí)現(xiàn)的效果。

一 動(dòng)畫(huà)效果

  看了這個(gè)效果之后我們來(lái)看看怎么來(lái)使用Form和FormItem控件,后面再進(jìn)一步分析這兩個(gè)控件的一些細(xì)節(jié)信息。

<xui:TabControl Canvas.Left="356" Canvas.Top="220">
                   <xui:TabItem Header="Overview">
                       <xui:Form Margin="2" >
                           <xui:FormItem Content="Test1" Height="30"></xui:FormItem>
                           <xui:FormItem Content="Test2" Height="30"></xui:FormItem>
                           <xui:FormItem Content="Test3" Height="30"></xui:FormItem>
                       </xui:Form>
                   </xui:TabItem>
                   <xui:TabItem Header="Plumbing">
                       <xui:Form Margin="2" Columns="2" Rows="2">
                           <xui:FormItem Content="Demo1" Height="30" Margin="5 2"></xui:FormItem>
                           <xui:FormItem Content="Demo2" Height="30" Margin="5 2"></xui:FormItem>
                           <xui:FormItem Content="Demo3" Height="30" Margin="5 2"></xui:FormItem>
                           <xui:FormItem Content="Demo4" Height="30" Margin="5 2"></xui:FormItem>
                       </xui:Form>
                   </xui:TabItem>
                   <xui:TabItem Header="Clean">
                       <xui:TextBox Text="Test2" Width="220" Height=" 30" Margin="5"></xui:TextBox>
                   </xui:TabItem>
               </xui:TabControl>

  這個(gè)里面xui命名控件是我們的自定義控件庫(kù)的命名空間,這個(gè)里面的TableControl也是一種特殊的自定義的TableControl,關(guān)于這個(gè)TableControl我們后面也會(huì)進(jìn)一步分析。

二 自定義控件實(shí)現(xiàn)

  按照上面的順序我們先來(lái)分析Form控件,然后再分析FormItem控件的實(shí)現(xiàn)細(xì)節(jié)

  2.1 Form

  通過(guò)上面的代碼我們發(fā)現(xiàn)Form是可以承載FormItem的,所以它是一個(gè)可以承載子控件的容器控件,這里Form是集成ItemsControl的,我們來(lái)看看具體的代碼

public class Form : ItemsControl
    {
        static Form()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Form), new FrameworkPropertyMetadata(typeof(Form)));
        }
 
        public double HeaderWidth
        {
            get { return (double)GetValue(HeaderWidthProperty); }
            set { SetValue(HeaderWidthProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for HeaderWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeaderWidthProperty =
            DependencyProperty.Register("HeaderWidth", typeof(double), typeof(Form), new PropertyMetadata(70D));
 
        public int Rows
        {
            get { return (int)GetValue(RowsProperty); }
            set { SetValue(RowsProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Rows.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RowsProperty =
            DependencyProperty.Register("Rows", typeof(int), typeof(Form), new PropertyMetadata(0));
 
        public int Columns
        {
            get { return (int)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Columns.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register("Columns", typeof(int), typeof(Form), new PropertyMetadata(1));
 
    }  

  然后我們?cè)賮?lái)看看Form的樣式文件

<Style TargetType="local:Form">
        <Setter Property="Padding" Value="10"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:Form">
                    <ScrollViewer Background="#eee" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                        <UniformGrid Columns="{TemplateBinding Columns}" Rows="{TemplateBinding Rows}" IsItemsHost="True" Background="Transparent" VerticalAlignment="Top" Margin="{TemplateBinding Padding}"></UniformGrid>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <ContentPresenter Content="{Binding}" Focusable="False"></ContentPresenter>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>  

  這里我們使用UniformGrid作為內(nèi)容承載容器,所以我們現(xiàn)在清楚了為什么需要定義Columns和Rows這兩個(gè)依賴項(xiàng)屬性了,這個(gè)UniformGrid是嵌套在ScrollerViewer中的,所以如果其子控件超出了一定范圍,其子控件外面是會(huì)顯示滾動(dòng)條的。

  2.2 FormItem

  FormItem是從ListBoxItem繼承而來(lái),而ListBoxItem又是從ContentControl繼承而來(lái)的,所以可以添加到任何具有Content屬性的控件中去,常見(jiàn)的ListBoxItem可以放到ListBox中,也可以放到ItemsControl中去,ListBoxItem可以橫向和TreeViewItem進(jìn)行比較,只不過(guò)TreeViewItem是直接從HeaderedItemsControl繼承過(guò)來(lái)的,然后再繼承自ItemsControl。兩者有很多的共同之處,可以做更多的橫向比較,我們今天只是來(lái)講ListBoxItem,首先看看我們使用的樣式,這里貼出前端代碼:

<Style TargetType="local:FormItem">
        <Setter Property="Margin" Value="0 0 0 15"></Setter>
        <Setter Property="Background" Value="#fff"></Setter>
        <Setter Property="Height" Value="50"></Setter>
        <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
        <Setter Property="VerticalAlignment" Value="Stretch"></Setter>
        <Setter Property="Padding" Value="6"></Setter>
        <Setter Property="Foreground" Value="{StaticResource DarkColor}"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:FormItem">
                    <Grid Background="{TemplateBinding Background}" Height="{TemplateBinding Height}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding HeaderWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:Form}}"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Rectangle Width="3" HorizontalAlignment="Left" Fill="{StaticResource Highlight}"></Rectangle>
                        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Left" Margin="13 0 0 0" Orientation="Horizontal">
                            <Image x:Name="Icon" Source="{TemplateBinding Icon}" Width="24" Height="24" Margin="0 0 10 0" VerticalAlignment="Center" HorizontalAlignment="Left"></Image>
                            <TextBlock Text="{TemplateBinding Title}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
                        </StackPanel>
                        <ContentPresenter Margin="{TemplateBinding Padding}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"></ContentPresenter>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Icon" Value="{x:Null}">
                            <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>  

  這里我們重寫(xiě)了ListBoxItem 的ControlTemplate,我們需要注意的一個(gè)地方就是我們使用了

<ContentPresenter Margin="{TemplateBinding Padding}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"></ContentPresenter> 

來(lái)替代ListBoxItem的Content,我們需要始終記住,只有控件擁有Content屬性才能使用ContentPresenter ,這個(gè)屬性是用來(lái)呈現(xiàn)控件的Content。

     另外一個(gè)需要重點(diǎn)介紹的就是FormItem這個(gè)類(lèi)中的代碼,這個(gè)控件在加載的時(shí)候所有的效果都是在后臺(tái)中進(jìn)行加載的,首先貼出相關(guān)的類(lèi)的實(shí)現(xiàn),然后再做進(jìn)一步的分析。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
 
namespace X.UI
{
    public class FormItem : ListBoxItem
    {
        static FormItem()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FormItem), new FrameworkPropertyMetadata(typeof(FormItem)));          
        }
 
        public FormItem()
        {
            System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
            transform.X = transform.Y = 100;
            Opacity = 0;
 
            IsVisibleChanged += FormItem_IsVisibleChanged;
        }
 
        void FormItem_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (this.Parent is Form)
            {
                if (!IsVisible)
                {
                    int index = (this.Parent as Form).Items.IndexOf(this);
                    System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
                    DoubleAnimation da = new DoubleAnimation()
                    {
                        From = 0,
                        To = 100,
                        EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
                    };
                    transform.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, da);
                    transform.BeginAnimation(System.Windows.Media.TranslateTransform.YProperty, da);
                    DoubleAnimation daopacity = new DoubleAnimation
                    {
                        From = 1,
                        To = 0,
                    };
                    this.BeginAnimation(UIElement.OpacityProperty, daopacity);
                }
                else
                {
                    int index = (this.Parent as Form).Items.IndexOf(this);
                    System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
                    DoubleAnimation da = new DoubleAnimation()
                    {
                        From = 100,
                        To = 0,
                        BeginTime = TimeSpan.FromMilliseconds(100 * (index + 1)),
                        Duration = TimeSpan.FromMilliseconds(666),
                        EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
                    };
                    transform.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, da);
                    transform.BeginAnimation(System.Windows.Media.TranslateTransform.YProperty, da);
                    DoubleAnimation daopacity = new DoubleAnimation
                    {
                        From = 0,
                        To = 1,
                        BeginTime = TimeSpan.FromMilliseconds(100 * (index + 1)),
                        Duration = TimeSpan.FromMilliseconds(666),
                        EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
                    };
                    this.BeginAnimation(UIElement.OpacityProperty, daopacity);
                }
            }
        }
 
        private T EnsureRenderTransform<T>(UIElement uiTarget)
            where T : Transform
        {
            if (uiTarget.RenderTransform is T)
                return uiTarget.RenderTransform as T;
            else
            {
                T instance = typeof(T).Assembly.CreateInstance(typeof(T).FullName) as T;
                uiTarget.RenderTransform = instance;
                return instance;
            }
        }
 
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(FormItem), new PropertyMetadata(""));
 
 
        public ImageSource Icon
        {
            get { return (ImageSource)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IconProperty =
            DependencyProperty.Register("Icon", typeof(ImageSource), typeof(FormItem), new PropertyMetadata(null));
 
    }
}  

     這里在FormItem的構(gòu)造函數(shù)中,添加了一個(gè)IsVisibleChanged事件,這個(gè)事件會(huì)在加載當(dāng)前控件的時(shí)候發(fā)生,另外當(dāng)當(dāng)前控件的屬性值發(fā)生變化的時(shí)候會(huì)觸發(fā)該效果。其實(shí)效果就是同時(shí)在X和Y方向做一個(gè)平移的效果,這個(gè)也是一個(gè)常用的效果。

     我們重點(diǎn)討論的是下面的這段代碼:     

private T EnsureRenderTransform<T>(UIElement uiTarget)
           where T : Transform
       {
           if (uiTarget.RenderTransform is T)
               return uiTarget.RenderTransform as T;
           else
           {
               T instance = typeof(T).Assembly.CreateInstance(typeof(T).FullName) as T;
               uiTarget.RenderTransform = instance;
               return instance;
           }
       }

  這里我們創(chuàng)建TranslateTransform的時(shí)候是使用的System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);這個(gè)方法,而不是每次都new一個(gè)對(duì)象,每次new一個(gè)對(duì)象的效率是很低的,而且會(huì)占據(jù)內(nèi)存,我們?nèi)绻呀?jīng)創(chuàng)建過(guò)當(dāng)前對(duì)象完全可以重復(fù)利用,這里我們使用了帶泛型參數(shù)的函數(shù)來(lái)實(shí)現(xiàn)當(dāng)前效果,typeof(T).Assembly.CreateInstance(typeof(T).FullName) as T,核心是通過(guò)程序集來(lái)創(chuàng)建對(duì)象,這種方式我們也是經(jīng)常會(huì)使用的,比如我們可以通過(guò)獲取應(yīng)用程序級(jí)別的程序集來(lái)通過(guò)Activator.CreateInstance來(lái)創(chuàng)建窗體等一系列的對(duì)象,這種通過(guò)反射的機(jī)制來(lái)擴(kuò)展的方法是我們需要特別留意的,另外寫(xiě)代碼的時(shí)候必須注重代碼的質(zhì)量和效率,而不僅僅是實(shí)現(xiàn)了某一個(gè)功能,這個(gè)在以后的開(kāi)發(fā)過(guò)程中再一點(diǎn)點(diǎn)去積累去吸收。

以上就是c# WPF中自定義加載時(shí)實(shí)現(xiàn)帶動(dòng)畫(huà)效果的Form和FormItem的詳細(xì)內(nèi)容,更多關(guān)于c# wpf實(shí)現(xiàn)帶動(dòng)畫(huà)效果的Form和FormItem的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

乌兰察布市| 东乌珠穆沁旗| 会理县| 黎平县| 仙桃市| 蒙自县| 九寨沟县| 全椒县| 咸宁市| 嘉兴市| 乐亭县| 八宿县| 奉化市| 阿合奇县| 称多县| 天长市| 中山市| 泽普县| 汾阳市| 阳江市| 延庆县| 抚远县| 海阳市| 通江县| 准格尔旗| 东阿县| 苗栗县| 东乌| 北宁市| 肥城市| 卢湾区| 宁武县| 中宁县| 师宗县| 镇康县| 金门县| 固镇县| 天全县| 读书| 隆尧县| 普安县|