zoukankan      html  css  js  c++  java
  • WPF学习之 数据绑定

    数据绑定的关键是

    System.Windows.Data.Binding
    它会把两个属性粘在一起,并在它们之间建立一条通道。

    最简单的绑定

    建立一个窗体

    <Window x:Class="eventCon.Window3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="数据绑定" Height="294" Width="443">
        <Grid x:Name="xxiu">
             <TextBlock HorizontalAlignment="Left" Margin="23,100,0,0" Name="textBlock1" Width="120" Height="21" VerticalAlignment="Top" Text="{Binding Name}" />
            <TextBlock Height="21" HorizontalAlignment="Left" Margin="43,0,0,53" Name="textBlock2" VerticalAlignment="Bottom" Width="120" Text="{Binding Sex}" />
        </Grid>
    </Window>

    在窗体里面有两个TextBlock对象

    然后创建一个数据对象

    public class user
    {
        public string Name
        {
            get;
            set;
        }
        public string Sex
        {
            get;
            set;
        }
    }

    最后我们为数据绑定建立通道

     user us = new user()
                {
                    Name = "修修",
                    Sex = ""
    
                };
     this.xxiu.DataContext = us;

    这里用DataContent把数据与xxiu这个容器联系在一起,然后在xaml页面上面用Binding把数据绑定起来。运行一下

    image 

    这里数据绑定的步骤

    1.创建数据对象 user us=new user()

    2.把数据对象映射到容器,DataContext=us 。在书上这里称之为数据上下文,所有的FrameworkElement的元素都会有数据上下文DataContext这个属性。

    3.为容器中的对象绑定数据 Binding Name

    数据绑定模式

    image

    数据绑定模式有三中绑定模式

    1. OneTime 一次绑定,属于绑定后就不在管的类型

    2. OneWay  单向绑定,属于绑定后数据源发生变化时更新,适用于变化的数据

    3. TwoWay  双向绑定,即数据在目标或数据源中都将通知对方

    我们把第一个简单例子中的绑定模式设置成OneWay ,在绑定中设置Mode=OneWay

    <TextBlock Margin="33,31,53,0" Name="textBlock1" Height="21" Grid.Column="0"  VerticalAlignment="Top" Text="{Binding Name,Mode=OneWay }" />
    <TextBlock Height="21" Margin="42,90,44,0" Name="textBlock2" Grid.Column="0" VerticalAlignment="Top" Text="{Binding Sex,Mode=OneWay}" />
            

    这样就完成了绑定模式的设置,当Mode没有设置时默认为OneWay。

    这里我们发现当我们的数据源发生了变化的时候,显示并没有更新。这是为什么呢。

    更改通知

    为了使源对象的更改能够传播到目标,必须实现INotifyPropertyChanged接口。INotifyPropertyChanged具有PropertyChanged事件,该事件通知绑定引擎源已经更改,以便引擎可以更新目标值【MSDN】

    现在我们对我们的对象实现INotifyPropertyChanged这个接口。

    这里我们需要引入

    using System.ComponentModel;

    然后修改数据源对象

    public class user:INotifyPropertyChanged
    {
        private string _name;
        private string _sex;
        public event PropertyChangedEventHandler PropertyChanged;
        public string Name
        {
            get { return _name; }
            set { _name = value;
            NotifyPropertyChanged("Name");
            }
        }
        public string Sex
        {
            get { return _sex; }
            set { _sex = value;
            NotifyPropertyChanged("Sex");
            }
        }
    
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
    }

    当属性发生变化时执行PropertyChanged通知值发生了变化。这样样我们在设置Mode的属性的时候就能够看到值变化的通知了

    绑定到对象集合

           可以将绑定对象视为一个对象,也可以将它视为一个对象集合。比如显示一个列表,为此,需要使用ItemsControl并通过DataTemplate重复此操作,以显示集合中的每一项。

            对于从ItemsPanel派生的控件都能够显示列表集合,如ListBox,ComboBox等。他们都具有ItemsSource属性,可以直接为该属性设置集合。

    比如我们为一个ComBoBox设置绑定。

         List<user> users = new List<user>(); 
         users.Add(new user(){Name = "贾宝玉", Sex = ""});
         users.Add( new user() { Name ="林黛玉",Sex =""});
         users.Add(new user() { Name = "薛宝钗", Sex = ""});
    
         comboBox1.ItemsSource = users;

    image

    数据绑定上去了,但是不是我们想要的结果。

    为什么会出现这种情况呢,它是显示的对象返回的ToString()。我们可以重写这个对象的ToString。

      public override string ToString()
      {
            return string.Format("姓名:{0}性别:{1}",_name,_sex);
      }

    image

    但是这样并不是很好用,是很难用,我们在做WinFrom的时候有一个绑定DisplayMenber可以用来设置数据集的绑定字段。这里提供了DisplayMenberPath这个属性。

     <ComboBox Margin="42,0,44,95" Name="comboBox1" Height="23" VerticalAlignment="Bottom"  DisplayMemberPath="Name"/>

    image

    这样就可以得到我们想要的结果了,但是这个似乎在有些时候也不能够满足我们的需求。

    这里就要用到数据模板了。通过ItemsControl控件定义数据模板。这里的数据模板和ASP.NET里面定义GridView的模板非常的相似。

    <ComboBox Margin="42,0,44,95" Name="comboBox1" Height="23" VerticalAlignment="Bottom"  >
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel  Orientation="Horizontal"> 
                         <TextBlock Text="{Binding Name}"></TextBlock>
                         <TextBlock Text="{Binding Sex}"></TextBlock> 
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

    这里我们只需要对ItemsControl.ItemTemplate 进行设置,并同时使用 DataTemplate 来定义数据对象的外观

    image 

    就得到我们所需要的值了,当然,我们可以把模板定义的非常有个性。

     <ComboBox Margin="42,0,44,95" Name="comboBox1" Height="23" VerticalAlignment="Bottom"  >
                <ComboBox.ItemTemplate>
                    <DataTemplate> 
                        <Grid Height="60" Margin="24,0,202,12" VerticalAlignment="Bottom" Grid.ColumnSpan="2">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="28*" />
                                <RowDefinition Height="32*" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="55*" />
                                <ColumnDefinition Width="95*" />
                            </Grid.ColumnDefinitions>
                            <Image  Grid.RowSpan="2" Margin="6,6,8,6" Name="image1" Stretch="Fill"   Source="/eventCon;component/image/1.png" />
                            <TextBlock Grid.Column="1" Margin="4,4,13,3" Name="textBlock3" Text="{Binding Name}" />
                            <TextBlock Margin="8,5,9,6" Name="textBlock4" Grid.Column="1" Grid.Row="1" Text="{Binding Sex}" />
                        </Grid>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

    image

    DataGrid控件

    在ASP.NET开发中常常要用到GridView控件,而做数据绑定用的最多的也是GridView控件的使用。

    我们把页面上面放一个DataGrid控件,还是用上面的数据集,只是把comboBox1替换成为dataGrid1

      List<user> users = new List<user>();
                users.Add(new user() { Name = "贾宝玉", Sex = "" });
                users.Add(new user() { Name = "林黛玉", Sex = "" });
                users.Add(new user() { Name = "薛宝钗", Sex = "" });
    
                dataGrid1.ItemsSource = users;

    image

    但是这个表头并不是我们想要的,我们希望Name的地方显示“姓名” sex的地方显示“性别”,这里我们就要用到自定义列,如果对ASP.NET的熟悉这个也是很好理解的

    我们给他添加两列,并指定Binding属性绑定到的列,让自动生成列为False

     <my:DataGrid AutoGenerateColumns="False" Margin="60,24,78,35" Name="dataGrid1" Background="AliceBlue" BorderBrush="Snow" Foreground="Chocolate" AlternatingRowBackground="Green" >
                <my:DataGrid.Columns>
                    <my:DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
                    <my:DataGridTextColumn Header="性别" Binding="{Binding Sex}" />
                </my:DataGrid.Columns>
    </my:DataGrid>

    image

    我们在做ComboBox 的时候使用了模板来显示一个很特别的格式,DataGrid中当然也是支持模板的,给DataGrid添加一个模板列,然后把在ComboBox中使用的模板拿过来用用。

    <my:DataGrid AutoGenerateColumns="False" Margin="12,22,43,37" Name="dataGrid1" Background="AliceBlue" BorderBrush="Snow" Foreground="Chocolate" AlternatingRowBackground="Green" >
                <my:DataGrid.Columns>
                    <my:DataGridTemplateColumn Header="人   物" Width="400">
                        <my:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate >
                                <Grid Height="60" Margin="24,0,202,12" VerticalAlignment="Bottom" Grid.ColumnSpan="2">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="28*" />
                                        <RowDefinition Height="32*" />
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="55*" />
                                        <ColumnDefinition Width="95*" />
                                    </Grid.ColumnDefinitions>
                                    <Image  Grid.RowSpan="2" Margin="6,6,8,6" Name="image1" Stretch="Fill"   Source="/eventCon;component/image/1.png" />
                                    <TextBlock Grid.Column="1" Margin="4,4,13,3" Name="textBlock3" Text="{Binding Name}" />
                                    <TextBlock Margin="8,5,9,6" Name="textBlock4" Grid.Column="1" Grid.Row="1" Text="{Binding Sex}" />
                                </Grid>
                            </DataTemplate>
                        </my:DataGridTemplateColumn.CellTemplate>
                        <my:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate />
                        </my:DataGridTemplateColumn.CellEditingTemplate>
                    </my:DataGridTemplateColumn>
                </my:DataGrid.Columns> 
            </my:DataGrid>

    image

    到这里发现很多的东西在ASP.NET中有些类似。

  • 相关阅读:
    MySQL(2)---Explain
    MySQL(1)---索引
    php 的 PHPExcel1.8.0 使用教程
    通过html5 的EventSource来进行数据推送
    centos6.6 下 安装 php7 按 nginx方式
    IIS PHP Warning: Unknown: open(c:\php\tmp\sess_xxx, O_RDWR) failed: Permission denied (13) in Unknown on line 0
    动态加载JS,并执行回调函数
    nginx 504 gateway time out
    php 账号不能同时登陆,当其它地方登陆时,当前账号失效
    php 函数中静态变量的问题
  • 原文地址:https://www.cnblogs.com/ac1985482/p/1727666.html
Copyright © 2011-2022 走看看