用MVVM模式开发中遇到的零散问题总结(2)
本节目录:
4.DataGrid数据源绑定到复杂格式(dynamic类的运用)
本系列文章快速导航:
1.解决动画属性被劫持问题
这个问题解决的方案比较多,这里我就说最适用的方法
案例如下:
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="roll" Axis="0,1,0" Angle="0"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
当我们用roll.BeginAnimation()执行动画后
roll.Angle = ;
将不起任何作用,roll.Angle一直保持动画结束后的值,我们需要在执行赋值之前解除对Angle属性的劫持
roll.BeginAnimation(AxisAngleRotation3D.AngleProperty, null);
roll.Angle = ;
这样就OK了。
其他的解决方法请看这位大侠博文http://www.cnblogs.com/alamiye010/archive/2009/08/26/1554539.html 讲的比MSDN还全....
2.设置页面焦点默认所在对象
我这里是要设置窗口的默认焦点,像winForm一样设置TabIndex=0已经无用了,这里是用Command把要设置焦点的对象传到了ViewModel,然后再执行Focus()来设置焦点,传递父对象用到了RelativeSource源 ,但是还是有个缺点,必须设定父对象的类型才能成功绑定,求方案...
view如下:
<TextBox TabIndex="0">
<i:Interaction.Triggers>
<i:EventTrigger>
<i:InvokeCommandAction Command="{Binding setFocus}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
viewModel:
public ICommand setFocus { get; set; }
public void setFocusMethod(TextBox control)
{
control.Focus();
control.SelectionStart = control.Text.Length;//光标定位到末尾
}
更多关于RelativeSource的知识,请参考:http://www.cnblogs.com/iwteih/archive/2010/02/03/1662891.html
这里我请教个问题:我要把Label的内容绑定到但前的系统时间,应该如何做呢?
<Label Margin="0,8,8,16.163"DataContext="{Binding Source={StaticResource DateTimeDataSource}}" Content="{Binding Now, Mode=OneWay}" />
这样使用时间是不会更新的,我也试过用timerEvent事件来触发绑定还是没用,求解释,当然了只能用XAML来实现。
更新:我已经解决了,用英文在google搜索了老外问的相同问题,原来DateTime.Now是静态资源的,它的更新,不会触发OnPropertyChanged通知到界面,所以只用Xaml来实现是不可能滴。我的解决方案如下:
ViewModel:
private void initCommand()
{
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds();
timer.Tick+=new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
OnPropertyChanged("timeNow");
}
public string timeNow { get { return DateTime.Now.ToString(" hh:mm:ss\r\nyyyy-M-d "); } }
View:
<Label Content="{Binding timeNow,Mode=OneWay}"/>
这样就实时更新了。关于时间的显示格式请参考:
http://msdn.microsoft.com/zh-cn/library/8kb3ddd4(v=VS.100).aspx
3.XAML模拟键盘按键
这里调用的是System.Windows.Forms.SendKeys.SendWait(str)方法,需要引用System.Windows.Forms.dll
str:为键值字符串代码。参考:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.sendkeys.aspx
你会发现字符串都是{TAB}、{LEFT}这种格式的,但是在XAML中我们{}是有特殊意义的,比如{Binding}
但是XAML还是留给了我们转义符,比如:
我们要给correctInput(string str)方法传递"{BS}"字符串
前台:
<Button Content="回删" CommandParameter="{}{BS}" Command="{Binding correctInput}"/>
在字符串的前面加上{}就可以转意了哦~~~
后台:
public ICommand correctInput { get; set; }
public void correctInputMethod(string str)
{
try
{
win.win.Dispatcher.Invoke(new Action(() =>
{
System.Windows.Forms.SendKeys.SendWait(str);//直接发送backspace按键消息
}));
}
catch (Exception exp)
{
errerLog(exp);
}
FireEventMethod("correctInputMethod");
}
此方法只能模拟键盘按键哦。鼠标的没用到,暂时没研究,有知道的兄弟告诉下
4.DataGrid数据源绑定到复杂格式(dynamic类的运用)
这节标题我都不知道该怎么取,因为情况的确够复杂的,就把我的情况说下,大家以后遇到这种问题可以向这个方面考虑。
我view上有一个DataGrid,由于事先商定WCF传的数据都是以dictionary<string,object>来传的,即数据传过来是这种形式的dictionary<string,dictionary<string,string>>,其中第一层的dictionary的每一项就是datagrid的一行,而里面那层的dictionary的key就是列名,value就是值,当然了每次传的数据列名也可能不一样,目的就是让这个数据显示在DataGrid上。要如何绑定呢?我对DataGrid研究不是很深,我只知道可以绑定到XML和List<T>型的数据集合上。而这个数据源应该具有通用性,所以T的类型也是不确定的。
说了这么多应该把情况说清楚了,下面该主角出场了:dynamic 类。这个类是可编译时动态添加它的属性和方法,具体介绍:http://msdn.microsoft.com/zh-cn/library/dd264741.aspx
遍历字典,然后根据列名动态添加dynamic实例的属性,并赋值。每完一行就添加到一个ObservableCollection<dynamic>对象中,这样就符合list<T>这种型式的数据结构了,可供DataGrid使用。
private ObservableCollection<ObservableCollection<dynamic>> _colDic;
/// <summary>
/// 集合型数据字典集合
/// </summary>
public ObservableCollection<ObservableCollection<dynamic>> colDic
{
get { return _colDic; }
set
{
_colDic = value;
OnPropertyChanged("colDic");//更新到界面
}
}
public void dicToColMethod(Dictionary<string, object> dic)
{
win.win.Dispatcher.Invoke(new Action(() =>
{
ObservableCollection<dynamic> items = new ObservableCollection<dynamic>();//
colDic.Add(new ObservableCollection<dynamic>());//向集合字典添加第一本字典
int dicNem = ;//记录第几本字典
int k = ;//记录是第几条数据
foreach (string i in dic.Keys)
{
//整个dataGrid绑定到的数据源
Dictionary<string, object> thisDic;
if (dic[i].GetType().Name.Contains("Dictionary"))
{
dynamic item = new ExpandoObject();
thisDic = dic[i] as Dictionary<string, object>;
foreach (string j in thisDic.Keys)
{
(item as IDictionary<string, object>).Add(j, thisDic[j]);
}
items.Add(item);
}
if (k % + == )//每10行做一页
{
items = new ObservableCollection<dynamic>();//
colDic.Add(new ObservableCollection<dynamic>());
dicNem++;
}
if (k % + == || k == dic.Keys.Count - )
colDic[dicNem] = items;
k++;
}
}));
}
XAML:
<DataGrid ItemsSource="{Binding colDic[1]}" FontSize="15" Margin="11.5,8,40,8" SelectionMode="Single" IsReadOnly="True" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<DataGrid.Columns>
<DataGridTextColumn Header="支付日期" Width="80" Binding="{Binding PayDate}"/>
<DataGridTextColumn Header="支付时间" Width="80" Binding="{Binding PayTime}"/>
<DataGridTextColumn Header="支付渠道" Width="160" Binding="{Binding PayChannel}"/>
</DataGrid.Columns>
</DataGrid>
因为界面里用了一个书本翻页的控件,所以Datagrid分页也必须创建多个Datagrid来绑定到每10页一个的ObservableCollection。这些不是重点了,重点是介绍了dynamic的牛X之处。
后记:
我的第一个MVVM实战项目也是我工作以来的第一个项目昨天结束了,虽然结果有点不尽人意,但也从中学到不少。MVVM的设计模式是我引进到公司,却只有我一人用,所以3层都由我来写,2个星期的时间,面对view的不断需求不断更新加上自助终端上的那配置...我表示压力很大,这也就是成长的一部分吧。这个系列的文章可能让人感觉莫不着头脑,但是这些都是我遇到的问题,各位可以收藏起来,说不定哪天就碰到和我一样的问题呢,o(∩_∩)o 哈哈~~马上又要进入到另外一个项目了,只要我在学习,这系列文章就会不断更新,因为我发现,要把解决问题的方法转换成经验最好的方法就是把它共享出来,这样可以N长时间后也能看懂自己写的什么。
用MVVM模式开发中遇到的零散问题总结(2)的更多相关文章
- 用MVVM模式开发中遇到的零散问题总结(4)——自制摄像头拍摄大头贴控件
原文:用MVVM模式开发中遇到的零散问题总结(4)--自制摄像头拍摄大头贴控件 一直有个疑问,为什么silverlight对摄像头支持这么好,WPF却一个库都没有....于是我各种苦恼啊,各种Code ...
- 用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机
原文:用MVVM模式开发中遇到的零散问题总结(5)--将动态加载的可视元素保存为图片的控件,Binding刷新的时机 在项目开发中经常会遇到这样一种情况,就是需要将用户填写的信息排版到一张表单中,供打 ...
- 用MVVM模式开发中遇到的零散问题总结(3)——自制正则表达式万能绑定转换器
原文:用MVVM模式开发中遇到的零散问题总结(3)--自制正则表达式万能绑定转换器 前言 最近接受了3个项目的洗礼,出差近3个月,各种北京.广州.昆明来回奔波,好久没写博客了,之前我觉得我遇到的问题都 ...
- 用MVVM模式开发中遇到的零散问题总结(1)
https://www.cnblogs.com/tong-tong/archive/2011/11/28/2250948.html
- 【WPF开发备忘】使用MVVM模式开发中列表控件内的按钮事件无法触发解决方法
实际使用MVVM进行WPF开发的时候,可能会用到列表控件中每行一个编辑或删除按钮,这时直接去绑定,发现无法响应: <DataGridTemplateColumn Header="操作& ...
- C/S模式开发中如何利用WebBrowser控件制作导航窗体
原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见 ...
- C# WPF开发之MVVM模式开发
MVVM模式由Model,View,ViewModel三部分组成. Model需继承INotifyPropertyChange(属性修改通知) ViewModel负责业务逻辑,连接View和Model ...
- Android 基于MVC的MVVM模式开发
由skay整理 http://blog.csdn.net/sk719887916/article/details/50386144 什么是MVVM 我们一步步来,从MVC开始. MVC 我们都知道, ...
- 简易的WPF MVVM模式开发
Model层 public class Song { private string _artistName; private string _songTitle; public string Song ...
随机推荐
- HTML Email 编写指南(转)
作者: 阮一峰 日期: 2013年6月16日 今天,我想写一个"低技术"问题. 话说我订阅了不少了新闻邮件(Newsletter),比如JavaScript Weekly.每周 ...
- 基于 Android NDK 的学习之旅-----JNI LOG 打印
程序都是调出来的. 下面我介绍下JNI层的log打印方法的使用,类似与Android sdk提供的log 1.Android 应用层 MainActivity.java 主要功能代码 a) ...
- PHP移动互联网开发笔记(8)——MySQL数据库基础回顾[2]
一.数据表 为了确保数据的完整性和一致性,在创建表时指定字段名称,字段类型和字段属性外,还需要使用约束(constraint),索引(index),主键(primary key)和外键(foregin ...
- 【hdu 3863】No Gambling
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65568/32768 K (Java/Others) Total Submission(s) ...
- easyui样式及js导入顺序及刷新回车的问题
在使用easyui时,需要导入样式表及其js文件,在导入时.不光要遵守jquery包在easyui包的前面,还需要把样式表放在js的前边 <link type="text/css&qu ...
- http协议头文件的控制信息(转)
通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成.HTTP的头域包括通用头,请求头,响应 ...
- 检索01-c#中基本数据类型和引用类型的区别
1.基本定义 基本数据类型包括:整型.浮点型.字符型.结构体.布尔型.日期时间.枚举类型等 引用类型包括:字符串.类.数组.接口等 堆定义:是一种特殊的树形数据结构,每个结点都有一个值,一般由程序员分 ...
- 使用蒲公英来发布iOS内侧版本
1.生成ipa包 这里不介绍正规的打包方式(选择真机调试-编译成功以后-工具product-archive-....) 下面介绍快速打包方式: 1)选择真机调试-编译成功以后右击下图.app文件,选择 ...
- 【p094】道路游戏
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有n个机器人工厂,两个相邻机器人工厂之间由 ...
- Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写(全部用POSIX C实现)
Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写实现了日志.原子操作.哈希字典.红黑树.动态库加载.线程.锁操作.配置文件.os适配层.事件驱动.工作队列.RPC.IPC ...