zoukankan      html  css  js  c++  java
  • [uwp开发]数据绑定那些事(2)

    接着上一篇来侃。

    二.实体到控件之间的绑定

      这儿不知道用实体这个词恰不恰当,凑活着理解就行了。他可以是一个类实例,也可以是一个集合。

      所以,相应的我们就引入两个Demo,第一个介绍用简单的类作为作为数据源,第二个就介绍用一个集合作为数据源

      废话不多说,来看demo,我先上代码,后上分析

      DEMO1:

      XAML页面

        <Page.Resources>
            <local:User x:Key="user"></local:User>
        </Page.Resources>
        <Grid>
            <StackPanel DataContext="{StaticResource user}" HorizontalAlignment="Center">
                <TextBlock x:Name="tbID" Text="{Binding Path=ID}"></TextBlock>
                <TextBlock x:Name="tbName" Text="{Binding Path=Name}"></TextBlock >
                <TextBlock x:Name="tbGender" Text="{Binding Path=Gender}"></TextBlock>
            </StackPanel>
        </Grid>

      

    User类:

      public class User
        {
            public int ID{get;set}
            public string Name{get;set}
            public string Gender{get;set;}
        }

    C#代码:

      public sealed partial class MyPage : Page
        {
            public MyPage()
            {
                this.InitializeComponent();
    User user
    =Resources["user"] as User; if (user != null) { user.ID = 10000; user.Name = "CQ"; user.Gender = "不明"; } } }

      上面两坨就是全部代码了,在这儿我说一下执行大概流程。

      在执行MyPage类的构造函数时,我们通过User user=Resources["user"] as User拿到定义在MyPage页面中的静态资源User类的实例,然后对其赋值,运行程序后,我们发现控件上显示出来了

      我们赋值的数据。

      其实,我们在xaml中定义了三个TextBlock控件用来显示User类中的三个属性,但是我们只在他们的binding中只声明了Path,并没有指定ElementName,也就是数据源,这时候他们会查找他们的父级

      元素的数据源,这个数据源必须含有ID,User,Gender三个属性。而在他们的父级元素StackPanel中定义了属性DataContext(数据上下文),它在这儿指明了数据源,是谁呢?就是“user”,它定义在静态

      资源中。然后在MyPage类的构造函数中,拿到了类User的实例,为他赋值后,最后通过数据绑定的技术,他们最终显示在屏幕上!注意:当他们显示后,如果人为修改了user类中的属性值,这种改变是

          不会在界面上显示出来的。如果想让它跟着变该怎么办?往下看!

      在Demo1中的代码实际是没有啥实际用途的,想要有用途的,我们把它改造一下!!!

      之前说了,我们需要在User类实例的属性值发生改变后,让改变后的数据也显示在界面上。所以做如下改动!只需要改动User类就可以了!

      

      public class User : INotifyPropertyChanged
        {
            private int _id;
            private string _name;
            private string _gender;
            public int ID
            {
                get
                {
                    return _id;
                }
    
                set
                {
                    _id = value;
                    OnPropertyChanged();
                }
            }
    
            public string Name
            {
                get
                {
                    return _name;
                }
    
                set
                {
                    _name = value;
                    OnPropertyChanged();
                }
            }
    
            public string Gender
            {
                get
                {
                    return _gender;
                }
    
                set
                {
                    _gender = value;
                    OnPropertyChanged();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void OnPropertyChanged([CallerMemberName]string propertyName="")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

      其实理解还是比较简单。试想,提供一种机制,在user属性改变后,就通知系统说“我的值变了,你丫赶紧给我再界面上表达出来”,那么这个机制就通过让User继承INotifyPropertyChanged这个

      接口来实现。

      对比这个类和之前的,除了实现了接口INotifyPropertyChanged接口外,还定义了一个公共方法OnPropertyChanged,其次所有的属性的set方法里加了OnPropertyChanged()方法,用来通知

      属性值发生了改变。

      提示小技巧:CallerMemberName特性的作用是在调用OnPropertyChanged方法时,把属性的名称作为参数传进入,如果不加的话,在调用时就需要手动输入属性名称,这样出错的几率就比较大!

      置于INotifyPropertyChanged的真正内部原理,请msdn!...其实是我不太懂!

      好了,做了如上一番修改后,就是先我们需要的功能了!

         DEMO2

      这次我们玩个有用的,吧一个集合中的数据绑定到一个列表中!

      先上代码!!!

      xaml:

        <StackPanel>
                <Button Content="改变" Click="Button_Click"></Button>
                <ItemsControl x:Name="itemsControl" ItemsSource="{Binding}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ID,Mode=OneWay}"/>
                                <TextBlock Text="{Binding Name,Mode=OneWay}" ></TextBlock>
                            </StackPanel>
                        </DataTemplate>
                       
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>

      product:

      public class Product
        {
            private int _id;
            private string _name;
            public int ID
            {
                get { return _id; }
                set
                {
                    _id = value;
                 }
            }
            public string Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                }
            }
        }

      c#:

      

      public sealed partial class MyPage : Page
        {
            List<Product> list = null;
            public MyPage()
            {
                this.InitializeComponent();
    
    
                list = new List<Product>
                {
                    new Product { ID=1,Name="土豆" },
                    new Product{ ID=2,Name="马铃薯"},
                    new Product{ ID=3,Name="洋芋"}
                   
                };
                
                itemsControl.ItemsSource = list;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                if (list != null)
                {
                    list.Add(new Product { ID = 4, Name = "Potato" });
                }
            }
        }

      

      这是运行结果。先不要在意那个“改变”按钮。

      这次定义了一个ItemsControl列表控件,并且对其ItemTemplate 定义了一个模板,知识还是数据绑定。不懂可以看我的这篇文章DataTemplate和ControlTemplate联系与区别

      然后定义了一个泛型集合List<Product>,添加了三条数据后,把它设置为ItemsControl的数据源,注意这儿不用DataContext设置,用ItemSource属性!(而这区别可以百度!)

      之后运行程序,发现数据已经成功显示在界面上了。

      到这儿,已经实现了如何把一个集合中的数据显示在一个列表控件中!

      而的“改变”按钮的作用是想List中添加一条数据,但在点击后,界面上并没有反应,但是通过调试发现,数据的确添加到了List中,知识没有显示出来而已,结合我们之前一篇博文,

      应该能猜到,这儿缺少某种通知机制。当我们把List<Product>换为ObservableCollection<Product>后,会发现能够改变数据了。

      通过查看定义发现ObservableCollection<T>实现了接口INotifyCollectionChanged, INotifyPropertyChanged,正是这两个接口提供了这种通知机制!

    至此。我的心得就完了。。但总感觉讲的不够,不清楚。以后把其中的小技巧在发篇博文谈谈。

      

  • 相关阅读:
    bzoj 2483: Pku2279 Mr. Young's Picture Permutations -- 钩子公式
    bzoj 3940: [Usaco2015 Feb]Censoring -- AC自动机
    bzoj 1059: [ZJOI2007]矩阵游戏 -- 二分图匹配
    bzoj 1911: [Apio2010]特别行动队 -- 斜率优化
    bzoj 1433: [ZJOI2009]假期的宿舍 -- 最大流
    bzoj 3944: Sum -- 杜教筛
    bzoj 3872: [Poi2014]Ant colony -- 树形dp+二分
    bzoj 1115: [POI2009]石子游戏Kam -- 博弈论
    (三)shiro的认证
    (二)spring初次遇见shiro
  • 原文地址:https://www.cnblogs.com/cjw1115/p/4888732.html
Copyright © 2011-2022 走看看