• 一个加载时带动画效果的ListBoxItem


        今天我们来谈一下ListBoxItem这个控件,ListBoxItem是直接从ContentControl继承而来的,所以可以添加到任何具有Content属性的控件中去,常见的ListBoxItem可以放到ListBox中,也可以放到ItemsControl中去,ListBoxItem可以横向和TreeViewItem进行比较,只不过TreeViewItem是直接从HeaderedItemsControl继承过来的,然后再继承自ItemsControl。两者有很多的共同之处,可以做更多的横向比较,我们今天只是来讲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>
    

      这里我们重写了ListBoxItem 的ControlTemplate,我们需要注意的一个地方就是我们使用了 <ContentPresenter Margin="{TemplateBinding Padding}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"></ContentPresenter>来替代ListBoxItem的Content,我们需要始终记住,只有控件拥有Content属性才能使用ContentPresenter ,这个属性是用来呈现控件的content。

         另外一个需要重点介绍的就是FormItem这个类中的代码,这个控件在加载的时候所有的效果都是在后台中进行加载的,首先贴出相关的类的实现,然后再做进一步的分析。     

    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的构造函数中,添加了一个IsVisibleChanged事件,这个事件会在加载当前控件的时候发生,另外当当前控件的属性值发生变化的时候会触发该效果。其实效果就是同时在X和Y方向做一个平移的效果,这个也是一个常用的效果。

         我们重点讨论的是下面的这段代码:     

     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;
                }
            }
    

      这里我们创建TranslateTransform的时候是使用的System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);这个方法,而不是每次都new一个对象,每次new一个对象的效率是很低的,而且会占据内存,我们如果已经创建过当前对象完全可以重复利用,这里我们使用了带泛型参数的函数来实现当前效果,typeof(T).Assembly.CreateInstance(typeof(T).FullName) as T,核心是通过程序集来创建对象,这种方式我们也是经常会使用的,比如我们可以通过获取应用程序级别的程序集来通过Activator.CreateInstance来创建窗体等一系列的对象,这种通过反射的机制来扩展的方法是我们需要特别留意的,另外写代码的时候必须注重代码的质量和效率,而不仅仅是实现了某一个功能,这个在以后的开发过程中再一点点去积累去吸收。

        

  • 相关阅读:
    双系统安装,引导被覆盖-如何解决?
    关于apue.3e中apue.h的使用
    UML类图关系
    设计模式的原则
    插入排序Insertion Sort
    Xcode intellisense meaning of letters in colored boxes like f,T,C,M,P,C,K,# etc
    asp.net mvc 页面内容呈现Html.Raw HtmlString
    sqlserver通过设计器修改表结构保存时提示:保存到文本问题
    在windows下使用Cygwin模拟unix环境,并安装apt-cyg,svn等工具
    vs2015插件推荐 Productivity Power Tools 2015
  • 原文地址:https://www.cnblogs.com/seekdream/p/5614734.html
Copyright © 2020-2023  润新知