TJU_SCS_C#学习笔记(9)
2015-05-22 19:48 blueContra 阅读(306) 评论(0) 编辑 收藏 举报这次的博客本应该在上个周末就贴上来,一拖再拖,拖到现在周五,然而周末还有最后一篇博客。 T T
由于上个礼拜并没有上课讲内容,看了做得比较好的同学们的成果展示,有的做游戏,有的写生活应用,有的想法奇特,有的技术超群,有的包装华丽……不得不说每个同学都非常有想法,我也感受到有个稳定的团队和明确的小组分工是多么高效的事情,然而我一个人组队在编写的过程中花费了太多的时间,如果有队友一块儿交流的话,我感觉我能做得更加好。
接下来我就讲一些我在编写代码过程中学习的知识。
1.WP的Navigation和WPF中的窗口跳转。
首先两者的实现是有区别的,在WP中基础的页面跳转只需要一行代码就能实现,非常的方便,我的代码中的某跳转如下:
var passId = String.Format("{0}",((TextBlock)e.OriginalSource).Name); Frame.Navigate(typeof(courseInfo),passId);
Frame.Navigate(typeof([页面的名称]),[待定的参数]),基本格式如次,后面的参数可有可无,看实际的需要可以传递不同类型的参数。
然而在WPF中的跳转是不同的。
首先WPF中分为窗口和页面,它们彼此之间的跳转有这区别。窗口Window是包含Page的,而不是Page包含Window。
登陆界面的跳转,也就是窗口的切换,可以写成如下的情况:
courseTable ct = new courseTable(); ct.Show(); this.Close();
这里courseTable是目的窗口的名称,在这里你要先将其实例化,然后调用show()这个成员函数,才能把他显示出来。
页面的跳转则分为前台转和后台转,前台转可以如下:
<TextBlock FontSize="24" TextWrapping="Wrap" Margin="0,0,0,-19.998"> <Hyperlink x:Name="LnkPre" NavigateUri="Page2.xaml" Foreground="Black"> Enter Page2 </Hyperlink> </TextBlock>
后台转可以有几种方法,如:
NavigationService.GetNavigationService(this).Navigate(new Uri("Page2.xaml", UriKind.Relative)); NavigationService.GetNavigationService(this).GoForward();向后转 NavigationService.GetNavigationService(this).GoBack(); 向前转
在后台跳转中,还有一个更简单的用法是:
this.content = new Page2();
然后window跳转page可以如下写法:
NavigationWindow window = new NavigationWindow(); window.Source = new Uri("Page1.xaml", UriKind.Relative); window.Show();
怎么说呢,还是WP开发的代码比较简洁 = =
上面提到了在WP应用中如何在页面之间传值,也是非常的方便,然而在WPF中情况又是不同。
首先在窗口之间传值有如下几种方式:
1. 声明个全局变量,就是App.xaml里面声明;在所有窗体里面都可以引用 Application.Current.Properties["ArgumentName"];
2. 第二个就是在目标窗体上面公开个属性,直接赋值;
3. 最后就是在Uri里面传参数 NavigationService.Navigate(window object,argument value)
4. 采用事件响应,传递值。
在http://www.cnblogs.com/fdyang/archive/2013/03/25/2980451.html这篇博客中例子讲的比较清楚。
2.关于binding。
WP中的数据binding一般采用MVVM的原则,也就是Model-View-View-Model就是将一些控件的值绑定到你的Model的一些属性上,这样可以根据你的Model中元素的个数,元素的属性来定义你的控件,这样代码的复用率比较高,效率也比较高。
在我的WP应用中我先需要写我的XAML中的DataTemplate,这样才能使用binding来讲我的后台与前端相连。这是我写的数据模版:
<GridView ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="GridView_ItemClick"> <GridView.ItemTemplate> <DataTemplate> <Border BorderBrush="Black" BorderThickness="1" Width="66" Height="110"> <TextBlock Text="{Binding CourseName}" FontSize="15" Foreground="Black" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" /> </Border> </DataTemplate> </GridView.ItemTemplate> </GridView>
首先这里ItemsSource="{Binding}"这里应该对应了我写在上面的这句代码:
DataContext="{Binding CourseViewModel, RelativeSource={RelativeSource Self}}"
这里的CourseViewModel是我绑定的对象,是一个我自定义的类的实例的集合容器。
首先,这是在GridView里定义Border中嵌入TextBlock的模版,意思也就是每对应一个CourseViewModel中的元素,就会在这里的GridView里添加一个嵌入有TextBlock的Border,然后TextBlock Text="{Binding CourseName}" 意思就是对应每一个元素,将TextBlock的内容设置成该元素的属性CourseName。
public static ObservableCollection<courseInfomation> CourseViewModel { get { return FiveDayCourses._courseViewModel; } }
上面Binding的CourseViewModel如上。
然后在写的过程中,我遇到了我修改我的CourseViewModel中的属性,然而控件中的内容并未同时更改的问题,后来才知道,binding只是在控件初始化的时候binding一遍,要实现我需要的实时刷新,要对目标类实现INotifyPropertyChanged这个接口,代码如下:
public class courseInfomation :INotifyPropertyChanged { public int courseId { get; set; } //public string courseName { get; set; } private string courseName; public string CourseName { get { return courseName; } set { if (value != this.courseName) { courseName = value; NotifyPropertyChanged("CourseName"); } } } public string teacherName { get; set; } public string place { get; set; } public TimeSpan startTime { get; set; } public TimeSpan endTime { get; set; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
我这个courseInfomation的类中,可见我的CourseName和其他属性有点不同,这是我设定的当CourseName这个属性在更改时会刷新binding,实现实施更新的效果。
binding还是挺值得研究的,然而我只是接触了皮毛。
这次的博客大概就是如此的了,在binding中我的WP APP还是有一些问题,关于Json初始化Model内容,也就是读取Json文件进入集合容器,和我代码中的初始化集合容器函数代码调用之间的逻辑问题,导致我Json文件写进去了,读不出来,binding不了,我会尽快找出这个逻辑的问题。
Go ahead! C#!