• WPF 神话之Binding对象二


        今天我们来探讨的问题,有两个:一是:关于Binding的几个属性问题(Path,Source) 二是:关于几种数据源问题。

        首先来看第一个问题:
     第一个属性:Source:这个数据源有很多种,在接下来我会大家提供几个数据源的例子信息。
     第二个属性:Path,这里将要重点介绍这个属性
     在XAML文件中写Binding的时候。这里的Path是可以不用写的。比如说:
     <GridViewColumn Header="Age"   Width="220" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
     这句话是说Binding一个数据源中的Age属性。这里的Path我是省略掉的。这种写法大家要习惯。

     再来看一种特殊情况。Path采用.来使用的类型。我们来看看这样的一个小例子。
     <Window x:Class="WpfBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"  // 这里我们使用了资源。所以要引用这个命名空间,请注意了。
            Title="MainWindow" Height="800" Width="800">
         <StackPanel>
      <!--定义资源-->
      <StackPanel.Resources>
          <sys:String x:Key="myResource">
       菩提本无树,明镜亦非台。
       本来无一物,何处惹尘埃。
          </sys:String>
      </StackPanel.Resources>
      <!--
      没有Path的Binding.
      1、如果一个数据源本来就是数据,如string,int等。我们可以不用指定Path.
      2、如我们下面的写法
      -->
      <TextBlock x:Name="txtMsg" TextWrapping="Wrap" Text="{Binding Path=.,Source={StaticResource ResourceKey=myResource}}" Margin="5" Background="LightBlue"/>
         </StackPanel>
     </Window>
     这个例子的呈现效果就是。我们看到了资源的信息。会显示出来。
     这里的Binding我们还可以写成这样{Binding .,Source={StaticResource ResourceKey=myResource}} 或者{Binding Source={StaticResource ResourceKey=myResource}}

        接下来我们来探讨第二个问题。关于数据源的问题。
       
        1.DataContext 这个属性是被定义在FrameworkElement类中的,而这个类是WPF控件的一个基类。所以我们WPF控件都有这个属性。
          如果我们在WPF中的某个控件上设置了Path属性,但是没有给定其的Source属性的话。WPF会自动在该控件树上向上查找。把第一个找到的DataContext作为自己的数据源。
       
        2、集合作为数据源的例子。
        代码清单如下:
        XAML:
        <Window x:Class="WpfBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            Title="MainWindow" Height="800" Width="800">
     <StackPanel>
     <!--DataSource的指定这里采用Grid来做布局-->
            <Grid Background="LightBlue">
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="5"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBox x:Name="txtStudentID" BorderBrush="Black" Margin="2"></TextBox>
                <ListBox x:Name="lstStudent" BorderBrush="Black" Height="100" Grid.Row="2">
                    <ListBox.ItemTemplate><!--使用模版来进行数据banding-->
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Path=Id}"  Width="100"/>
                                <TextBlock Text="{Binding Path=Name}"  Width="100"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
     </StackPanel>
        </Window>
       
        来看看后台代码
        在后台的初始化中添加这段代码。这里有个Member类。该类里面就两个属性。一个是Id,一个是Name.请各位自己添加一个类就好。
        List<Member> lstMember = new List<Member>(){
                    new Member("0001","wy"),
                    new Member("0002","love"),
                    new Member("0003","hu"),
                    new Member("0004","bing"),
                    new Member("0001","wy")
                };

                this.lstStudent.ItemsSource = lstMember; // 这里是将我们的数据源给我们的ListBox。关于这点大家应该都很清楚。winform大家应该接触过。
                // this.lstStudent.DisplayMemberPath = "Name";
      
         // 主要来看这段代码。这段代码的意思是
         // 把我们的ListBox作为我们的数据源。目标是我们的文本框。
         // 绑定的对象属性是该数据源中的Id,这里是用的SelectedItem.Id
         // 也就是说选中行的Id.从这里我们就清楚了,这个例子不但进行了数据banding。而且还进行选中行的数据Id同其他控件进行关联
         // 请大家运行下代码看看效果。
                Binding bind = new Binding("SelectedItem.Id") { Source = this.lstStudent };
                this.txtStudentID.SetBinding(TextBox.TextProperty, bind);
      
        3.我们再来看另外几个数据源的情况。
          XAML:
          <Window x:Class="WpfBinding.BindingWin"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="BindingWin" Height="600" Width="600">
        <StackPanel>
            <ListView x:Name="lvStudent" Height="200">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="ID" Width="150" DisplayMemberBinding="{Binding ID}"></GridViewColumn>
                        <GridViewColumn Header="Name" Width="200" DisplayMemberBinding="{Binding StuName}"></GridViewColumn>
                        <GridViewColumn Header="Age"   Width="220" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <DockPanel>
                <Button x:Name="btnFromDataTable" Content="从DataTable获取数据" Click="btnFromList_Click" Width="150"></Button>
                <Button x:Name="btnFromXml" Content="从XML中获取数据" Click="btnFromList_Click" Width="150"></Button>
                <Button x:Name="btnObjectDataProvider" Content="ObjectDataProvider" Click="ObjectDataProvider_Click" Width="130"></Button>
            </DockPanel>
     </StackPanel>
           </Window>

           这几个例子会用到一个辅助类
          public class MyStudent {
            public string ID { get; set; }
            public string  StuName { get; set; }
            public int Age { get; set; }

            public MyStudent(string id,string name,int age)
            {
                this.ID = id;
                this.StuName = name;
                this.Age = age;
            }

            public MyStudent()
            {
                // TODO: Complete member initialization
            }
        }
         
          A.来看看DataTable作为数据源的例子
            在按钮btnFromDataTable事件中添加如下代码
         DataTable dt = new DataTable();
         dt.Columns.Add("ID", typeof(string));
         dt.Columns.Add("Name", typeof(string));
         dt.Columns.Add("Age", typeof(int));

         DataRow row1 = dt.NewRow();
         row1["ID"] = "0001";
         row1["Name"] = "Wy";
         row1["Age"] = 25;

         DataRow row2 = dt.NewRow();
         row2["ID"] = "0002";
         row2["Name"] = "Test121";
         row2["Age"] = 24;


         DataRow row3 = dt.NewRow();
         row3["ID"] = "0003";
         row3["Name"] = "Info001";
         row3["Age"] = 25;

         dt.Rows.Add(row1);
         dt.Rows.Add(row2);
         dt.Rows.Add(row3);

         // 记住这里一定要用DefaultView.请大家注意了。大家可以试验下直接把dt赋值过去的效果。
         this.lvStudent.ItemsSource = dt.DefaultView;

         /*
          以上还有一种写法
          this.lvStudent.DataContext = dt;
          this.lvStudent.SetBinding(ListView.ItemSourceProperty,New Binding());
          使用这种方法。Binding会自动找到DefaultView
         */
          B.使用XML文件作为数据源的形式 我这里有个XML文件。我是放在编译目录下的。也就是和我们生成的exe文件在同一个目录。
            <?xml version="1.0" encoding="utf-8"?>
     <StudentList>
      <Student Id="001" Name="Li" Age="25">
      </Student>
      <Student Id="002" Name="Ming" Age="24">
      </Student>
      <Student Id="003" Name="Wang" Age="20">
      </Student>
      <Student Id="004" Name="Hu" Age="25">
      </Student>
      <Student Id="005" Name="Xiao" Age="24">
      </Student>
     </StudentList>

     后台的代码如下:

     // 首先是加载我们的XML文件的内容,然后将这个XDocument文件进行数据的提取
     XDocument doc = XDocument.Load(System.AppDomain.CurrentDomain.BaseDirectory + "Xml.xml");
     this.lvStudent.ItemsSource = from element in doc.Descendants("Student") // 寻找Student节点
         select new MyStudent() {
             ID = element.Attribute("Id").Value,
             StuName =element.Attribute("Name").Value,
             Age = Convert.ToInt32(element.Attribute("Age").Value)
         };

            这里大家可以尝试着试验下。

     还有一种加载XML文件的方式。是这样的。大家看下面一个例子:
     <!--
                加载XML文件的数据
                1、加载xml文件中的数据用Xpath。
                2、加载的是属性值的时候用@Id
                3、如果加载的是子集元素的值就直接用其标签名
            -->
            <ListView x:Name="XmlDataSource" >
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="ID" DisplayMemberBinding="{Binding XPath=@Id}" Width="120"></GridViewColumn>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=Name}" Width="120"></GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button x:Name="BtnShowData" Content="显示数据" Click="BtnShowData_Click"></Button>

     这里很简单。就是一个显示内容的容器。一个按钮。
     这里有点申明。XPath=@Id是说明绑定的是Id这个属性 XPath=Name是说明加载Name节点的内容。这里就是有@和没有@的区别。请大家一定要注意。

     我们来看看XML文件的结构:
     <?xml version="1.0" encoding="utf-8"?>
     <StudentList>
      <Student Id="001">
       <Name>Wang</Name>
       <Age>25</Age>
      </Student>
      <Student Id="002">
       <Name>Yu</Name>
       <Age>24</Age>
      </Student>
      <Student Id="003">
       <Name>Zhang</Name>
       <Age>20</Age>
      </Student>
      <Student Id="004">
       <Name>Ping</Name>
       <Age>25</Age>
      </Student>
      <Student Id="005">
       <Name>Li</Name>
       <Age>24</Age>
      </Student>
     </StudentList>

     我们来看看按钮下面是怎么来加载XML文件并且显示在我们的UI上的。
     这里给出两种写法:

         /* 第一种加载方式
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load("MyXml.xml");

                XmlDataProvider xp = new XmlDataProvider();
                xp.Document = xmlDoc;
               
                // 暴露要绑定的数据
                xp.XPath = @"/StudentList/Student";

                this.XmlDataSource.DataContext = xp;
                this.XmlDataSource.SetBinding(ListView.ItemsSourceProperty, new Binding());

         /*第二种加载方式*/
                XmlDataProvider xmlPror = new XmlDataProvider();
               
                xmlPror.Source = new Uri(System.AppDomain.CurrentDomain.BaseDirectory+"MyXml.xml");
                xmlPror.XPath = @"/StudentList/Student";
                this.XmlDataSource.DataContext = xmlPror;
                this.XmlDataSource.SetBinding(ListView.ItemsSourceProperty, new Binding());

      /*
       这里的两种加载。对于XML文件的路径写法是不一样的。这点要注意啊。第一种可以使绝对路径。也可是相对路径。
       而第二种是一种URI的形式。

       可以看出第二种形式是第一种方式的一种简写。
      */

       又到了凌晨了。好了,各位。今天的说明就到这里啊。我们下次再来探讨WPF其他内容。今天就到这里了。各位晚安。美梦。

  • 相关阅读:
    Spark Mllib里的向量标签概念、构成(图文详解)
    Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)
    Spark Mllib里的Mllib基本数据类型(图文详解)
    [转]Debugging into .NET Core源代码的两种方式
    [转]在ASP.NET Core使用Middleware模拟Custom Error Page功能
    [转]Asp.net MVC中的ViewData与ViewBag
    [转]细说 ASP.NET Cache 及其高级用法
    [转]分布式中使用Redis实现Session共享(二)
    [转]Asp.net Core 使用Redis存储Session
    [转]JS跨域解决方式 window.name
  • 原文地址:https://www.cnblogs.com/heardawn/p/MyDawn.html
Copyright © 2020-2023  润新知