[Silverlight]山寨方法->扩展方法->Behavior以及一些遗憾
2009-12-24 20:46
453 查看
在我前两日的博文让DataGrid支持滚轮的山寨方法中所提到的方法非常Dirty,由于本人较懒且项目中只有一个地方应用了这个滚轮设计所以也未将其封装起来。所以嘛。。想复用就得ctrl+c、ctrl+v(这年头这种做法的确雷人)。
(注:这兄弟原文中用的是匿名委托,本着能少写就少写的理念,那部分给小改成Lambda了)
通过扩展方法和使用泛型,使得方法的复用性大大增加
调用方式
的确是很方便~
ok,第一步改造就此结束
调用方式
这个调用方式看起来不如扩展方法
非静态,需要实例化
必须Attach,没有扩展方法那么优雅
但其实Behavior的真正意义在于可以在XAML中应用。也就是说Developer封装过的方法,Designer不用知道它到底是如何实现的,只要清楚它是用来做什么的就可以了。美工可以通过Blend非常方便的使用Behavior,在XMAL的标记方式为
看上去的确很爽。但为什么我们在这里要使用代码调用的方式而非XAML标记呢?这的确是个遗憾。
关键就在于:<T>---对,就是泛型。XAML中并不支持泛型的声明(这点在WPF中稍好一些,不过依然很弱)。
如果强制的使用Person那么就丧失了Behavior的灵活性,还不如不封装。
这同时也证明我这个例子并不非常适合封装成Behavior
现在我知道的解决方案也只能是苦等盼望随着.NET4.0而来的XAML2009了。
或许您有更好的方法,何不告诉我呢?
扩展方法
不过天底下有懒人就有勤快人,在那篇文章的回复中,dongdongha[未注册用户]兄弟将此方法提炼了出来以便复用,代码如下:public static void SetMouseScroll<T>(this DataGrid dataGrid) { dataGrid.MouseWheel += (sender, e) => { DataGrid dataGrid1 = sender as DataGrid; if (dataGrid.ItemsSource == null) return; if (!e.Handled) { int rowsToMove = e.Delta / 120 * -1; if (e.Delta > 0) { if (dataGrid1.SelectedIndex + rowsToMove < 0) return; } else { if (dataGrid1.SelectedIndex + rowsToMove > dataGrid1.ItemsSource.Cast<T>().ToList().Count - 1) return; } dataGrid1.SelectedIndex = dataGrid1.SelectedIndex + rowsToMove; dataGrid1.ScrollIntoView(dataGrid1.SelectedItem, dataGrid1.Columns[0]); } }; }
(注:这兄弟原文中用的是匿名委托,本着能少写就少写的理念,那部分给小改成Lambda了)
通过扩展方法和使用泛型,使得方法的复用性大大增加
调用方式
dataGrid1.SetMouseScroll<Person>();
的确是很方便~
ok,第一步改造就此结束
Behavior
接下来由于我在原文中提到了Behavior,所以就干脆用Behavior再封装一次,核心代码其实还是上面的。public class DataGridMouseWheelBehavior<T> : Behavior<DataGrid> { public string TypeOfBehavior { get; set; } public DataGridMouseWheelBehavior() { } protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded); } void AssociatedObject_Loaded(object sender, RoutedEventArgs e) { DataGrid dg = sender as DataGrid; dg.MouseWheel += (s2, e2) => { if (!e2.Handled) { int rowsToMove = e2.Delta / 120 * -1; if (e2.Delta > 0) { if (dg.SelectedIndex + rowsToMove < 0) return; } else { if (dg.SelectedIndex + rowsToMove > dg.ItemsSource.Cast<T>().ToList().Count - 1) return; } dg.SelectedIndex = dg.SelectedIndex + rowsToMove; dg.ScrollIntoView(dg.SelectedItem, dg.Columns[0]); } }; } protected override void OnDetaching() { base.OnDetaching(); } }
调用方式
var mousebehavior = new DataGridMouseWheelBehavior<Person>(); mousebehavior.Attach(dataGrid1);
这个调用方式看起来不如扩展方法
非静态,需要实例化
必须Attach,没有扩展方法那么优雅
但其实Behavior的真正意义在于可以在XAML中应用。也就是说Developer封装过的方法,Designer不用知道它到底是如何实现的,只要清楚它是用来做什么的就可以了。美工可以通过Blend非常方便的使用Behavior,在XMAL的标记方式为
<i:Interaction.Behaviors> <local:DataGridMouseWheelBehavior /> </i:Interaction.Behaviors>
看上去的确很爽。但为什么我们在这里要使用代码调用的方式而非XAML标记呢?这的确是个遗憾。
关键就在于:<T>---对,就是泛型。XAML中并不支持泛型的声明(这点在WPF中稍好一些,不过依然很弱)。
如果强制的使用Person那么就丧失了Behavior的灵活性,还不如不封装。
这同时也证明我这个例子并不非常适合封装成Behavior
现在我知道的解决方案也只能是苦等盼望随着.NET4.0而来的XAML2009了。
或许您有更好的方法,何不告诉我呢?
相关文章推荐
- IEnumerable<T>与IQueryable<T>以及.net的扩展方法
- jQuery ajax —— 一些细节以及主函数扩展出来的方法
- 开发 chrome 扩展 GitHub-Remarks 的一些想法以及遗憾
- 近期收集一些基于IEnumerable<T>扩展方法,它给我们带了很多便利,有时的确是实用的。其中有Alternate,Append,Prepend,Distinct,Contains。具体怎么用呢
- TextView加链接的一些方法以及设置个别文字格式
- c#扩展方法奇思妙用高级篇三:Enumerable.Cast<T>应用
- 一个IE8 Bug的解决方法以及一些思考
- 用python模仿c#的List<>一组list筛选扩展方法
- 关于C#3.0新特性以及扩展方法!
- PowerDesigner16.5快速入门显示,注释comment配置方法,以及创建sql文件过程中需要注意的一些问题
- JAVA中的protected(详解),以及和clone()方法有关的一些问题
- 开车误闯红灯的补救方法 (以及由此引发的一些思考)
- 使用扩展方法将DataTable转换为List<T>
- [Silverlight] 写了两个方便 DOM 查找的扩展方法
- java反射的补充:桥接方法以及Spring中一些工具类
- 修改MySQL 5.7.9版本的root密码方法以及一些新变化整理
- Xcode有许多快捷键,这些快捷键在Xcode的工具栏里都有标注,学会使用这些快捷键可以大大的提高你的编程效率。本文来给大家介绍一些Xcode常用快捷键,设置方法:Xcode主菜单->Xcode->P
- jsTree新版本>v1.0的一些方法
- c# 扩展方法奇思妙用高级篇三:Enumerable.Cast<T> 应用
- Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用