今天我们来谈一下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 = ;
Opacity = ; 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 = ,
To = ,
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 = ,
To = ,
};
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 = ,
To = ,
BeginTime = TimeSpan.FromMilliseconds( * (index + )),
Duration = TimeSpan.FromMilliseconds(),
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 = ,
To = ,
BeginTime = TimeSpan.FromMilliseconds( * (index + )),
Duration = TimeSpan.FromMilliseconds(),
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来创建窗体等一系列的对象,这种通过反射的机制来扩展的方法是我们需要特别留意的,另外写代码的时候必须注重代码的质量和效率,而不仅仅是实现了某一个功能,这个在以后的开发过程中再一点点去积累去吸收。

一个加载时带动画效果的ListBoxItem的更多相关文章

  1. 利用css实现页面加载时旋转动画

    有时浏览一些网站时在刚加载页面时候会出现一个滚动动画如下图,特别是对于一些移动端的站点或者混合应用来说应该用户体验会好很多,扒了下页面发现是用css样式控制的,于是把页面以及css样式赋值了下来, h ...

  2. CSS3实现加载中的动画效果

    本篇文章由:http://xinpure.com/css3-implementations-of-loading-an-animation-effect/ Loading 的菊花图形组合的不太好,基本 ...

  3. tableView//collectionView加载时的动画

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:( ...

  4. presentModalViewController方法,present一个透明的viewController,带动画效果

    //假设需要被present的控制器实例为controller,controller的背景色设置为clearColor UIViewController * rootcontroller = self ...

  5. 【Web前沿技术】纯 CSS3 打造的10个精美加载进度条动画

    之前向大家介绍8款优秀的 jQuery 加载动画和进度条插件,今天这篇文章向大家推荐10个纯 CSS3 代码实现精美加载进度条动画效果的方案.加载动画和进度条在网站和 Web 应用中的使用非常流行,特 ...

  6. 页面加载中jquery逐渐消失效果实现

    为了获得更好的用户体验,现在大多数网页都会在页面中加一个加载中效果,这里实现一个加载中逐渐消失的效果,以至于看上去不那么生硬. html: <div id="loading" ...

  7. 页面加载时的div动画

    用@keyframes(动画),实现页面加载时的div动画(不要用js控制,因为当页面加载的时候,js还不一定可以使用) 可以在https://daneden.github.io/animate.cs ...

  8. ionic js 加载动画 ionSpinner 提供了许多种旋转加载的动画图标。当你的界面加载时,你就可以呈现给用户相应的加载图标。 该图标采用的是SVG

    ionic 加载动画 ion-spinner ionSpinner 提供了许多种旋转加载的动画图标.当你的界面加载时,你就可以呈现给用户相应的加载图标. 该图标采用的是SVG. 用法 <ion- ...

  9. 收藏一个带动画效果的ScrollViewer以及ScrollBar的模板

    这里介绍一个带动画效果的ScrollViewer和ScrollBar,总共分为两个资源字典,直接拿来引用即可: 1 ScrollBarStyle.xaml <ResourceDictionary ...

随机推荐

  1. python subprocess.Popen 控制台输出 实时监控百度网ping值

    import subprocess file_out = subprocess.Popen('ping www.baidu.com', shell=True, stdout=subprocess.PI ...

  2. [matlab] 15.罚函数降维

    求非线性规划 min f(x)= x(1)^2 + x(2)^2 + 8 s.t. { x(1)^2-x(2)>=0 , -x(1) - x(2)^2 +2 = 0, x(1)>=0 ,x ...

  3. Android 6.0以后的版本报错:open failed: EACCES (Permission denied)

    Android 6.0以后的版本报错:open failed: EACCES (Permission denied) 在开发项目中,遇见要进行文件操作,遇见Caused by: android.sys ...

  4. 【转】FFmpeg 基本用法

    FFmpeg FFmpeg 基本用法 本课要解决的问题 1.FFmpeg的转码流程是什么? 2.常见的视频格式包含哪些内容吗? 3.如何把这些内容从视频文件中抽取出来? 4.如何从一种格式转换为另一种 ...

  5. linux 应用和发展

      课程大纲  UNIX/Linux发展历史  自由软件  Linux应用领域  Linux学习方法   UNIX 发展历史 (1 )1965年,美国麻省理工学院(MIT). 通用电气公司(G ...

  6. 转发 .Net平台下ActiveMQ入门实例 https://www.cnblogs.com/madyina/p/4121458.html

    1.ActiveMQ简介 先分析这么一个场景:当我们在网站上购物时,必须经过,下订单.发票创建.付款处理.订单履行.航运等.但是,当用户下单后,立即跳转到“感谢那您的订单” 页面.不仅如此,若果没有延 ...

  7. 吴恩达课后作业学习2-week3-tensorflow learning-1-例子学习

    参考:https://blog.csdn.net/u013733326/article/details/79971488 使用TensorFlow构建你的第一个神经网络 我们将会使用TensorFlo ...

  8. 关于NOIP2018复赛若干巧合的声明

    关于NOIP2018复赛若干巧合的声明 导言 参加NOIP2018时本人学龄只有两个月,却斩获了省一等奖,保送了重点中学的重点班,这看上去是个我创造的神话,然而,在我自己心中,我认为这只是个巧合(其实 ...

  9. hibernate 解决 org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

    这是因为没有设置要更新的主键导致的,只要设置了要更新的主键就能更新成功(没有主键当然不能更新)

  10. Git&Github基本操作与分支管理

    Git的原理涉及快照流.链表.指针等,这里不作过多叙述. 1.基本操作 git init 创建一个 Git 仓库 git clone [url] 拷贝一个 Git 仓库到本地 git add [fil ...