代码改变世界

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#!