WPF入门教程系列十八——WPF中的数据绑定(四)

六、排序

     如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider。CollectionViewSource 则会成为数据源,并充当截取 ObjectDataProvider 中的数据的媒介,并提供排序、分组和筛选功能,然后将它传送到目标。

     这个显示是使用 CollectionViewSource做为排序的数据源,首先将CollectionViewSource的Source 属性设置为 ObjectDataProvider的资源名称。然后通过设置CollectionViewSource.SortDescriptions属性,指定排序字段和排序顺序:

 <CollectionViewSource x:Key="studentsView" Source="{Binding Source={StaticResource students}}">

                    <CollectionViewSource.SortDescriptions>

                        <scm:SortDescription PropertyName="Name" Direction="Ascending" />

                        <scm:SortDescription PropertyName="Age" Direction="Descending" />

                    </CollectionViewSource.SortDescriptions>

                </CollectionViewSource>

     WPF中的DataContext属性是非常有用的,如果你有多个控件需要绑定同一个数据源,那么按照WinForm中的做法是给每个控件都绑定一次数据源,那么做重复代码就会很多。而在WPF中你可以首先把这些需要绑定同一个数据源的控件放在同一个容器控件内,然后将容器控件的 DataContext 设置为绑定源,容器内的控件的数据源绑定就可以不必再绑定,使用容器的数据源。例如,下面

的示例:StackPanel的 DataContext 属性绑定了数据源,DataGrid就可以不必再次绑定了,直接使用StackPanel绑定的数据源。 

<StackPanel DataContext="{StaticResource studentsView}">

            <TextBlock Width="248" Height="24" Text="数据排序:"

        TextWrapping="Wrap"/>

            <DataGrid  AutoGenerateColumns="False"   

                ItemsSource="{Binding}" CanUserAddRows="False">

             

                <DataGrid.Columns>

                    <DataGridTextColumn Binding="{Binding Name}" Header="名称" />

                    <DataGridTextColumn Binding="{Binding Age}" Header="年龄" />

                    <DataGridTextColumn Binding="{Binding Country}" Header="国家" />

                    <DataGridTextColumn Binding="{Binding Birthday}" Header="出生日期" />

                </DataGrid.Columns>

            </DataGrid>

            </StackPanel>

     如果该容器没有定义 DataContext,那么它会继续查找下一个外部嵌套容器,直到它找到当前的 DataContext 为止。如下图所示。当点击列头时,数据就会进行顺序或逆序排序。如下图。

 WPF入门教程系列十八——WPF中的数据绑定(四)

整个示例的全部代码如下:

<Window x:Class="WpfApp1.WindowBindData"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:local="clr-namespace:WpfApp1.Services"

        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"

        Title="WindowBindData" Height="700" Width="500">

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition Height="140"/>

            <RowDefinition Height="150"/>

            <RowDefinition Height="140"/>

           

            <RowDefinition Height="100*"/>

        </Grid.RowDefinitions>

 

        <StackPanel Grid.Row="0">

            <TextBlock Width="248" Height="24" Text="股票名称:"

        TextWrapping="Wrap"/>

            <ListBox x:Name="listStockName" Width="248" Height="56">

                <ListBoxItem Content="全通教育"/>

                <ListBoxItem Content="大智慧"/>

                <ListBoxItem Content="宝钢股份"/>

                <ListBoxItem Content="浦发银行"/>

                <ListBoxItem Content="工商银行"/>

                <ListBoxItem Content="中国建筑"/>

                <ListBoxItem Content="中国南车"/>

            </ListBox>

            <TextBlock Width="248" Height="24" Text="你所选中的股票名称:" />

            <TextBlock Width="248" Height="24" Text="{Binding ElementName=listStockName, Path=SelectedItem.Content}">

            

            </TextBlock>

        </StackPanel>

        <StackPanel Grid.Row="1">

            <TextBlock Width="248" Height="24" Text="颜色:"

        TextWrapping="Wrap"/>

            <ListBox x:Name="listColor" Width="248" Height="56">

                <ListBoxItem Content="Blue"/>

                <ListBoxItem Content="Red"/>

                <ListBoxItem Content="Green"/>

                <ListBoxItem Content="Gray"/>

                <ListBoxItem Content="Cyan"/>

                <ListBoxItem Content="GreenYellow"/>

                <ListBoxItem Content="Orange"/>

            </ListBox>

            <TextBlock Width="248" Height="24" Text="改变背景色:" />

            <TextBlock Width="248" Height="24" Text="{Binding ElementName=listColor, Path=SelectedItem.Content, Mode=OneWay}"

                       Background="{Binding ElementName=listColor, Path=SelectedItem.Content, Mode=OneWay}">

 

            </TextBlock>

            <TextBox Name="txtTwoWay" Text="{Binding ElementName=listColor,Path=SelectedItem.Content,Mode=TwoWay}"

                     Background="{Binding ElementName=listColor,Path=SelectedItem.Content,Mode=TwoWay}"></TextBox>

        </StackPanel>

 

 

        <StackPanel Grid.Row="2">

            <StackPanel.Resources>

                <XmlDataProvider x:Key="MyColors"  Source="Colors.xml"  XPath="colors">

                  

                </XmlDataProvider>

 

            </StackPanel.Resources>

            <TextBlock Width="248" Height="24" Text="XML数据绑定:"

        TextWrapping="Wrap"/>

            <ListBox x:Name="listXmlColor" Width="248" Height="56" IsSynchronizedWithCurrentItem="True"

                     ItemsSource="{Binding Source={StaticResource MyColors},[email protected]}">

             

            </ListBox>

            <TextBlock Width="248" Height="24" Text="选中的颜色:" />

            <TextBlock Width="248" Height="24" Text="{Binding ElementName=listXmlColor,  Path=SelectedValue, Mode=OneWay}"

                     >

 

            </TextBlock>

        

        </StackPanel>

 

 

        <StackPanel Grid.Row="3">

            <StackPanel.Resources>

                <ObjectDataProvider x:Key="students"  ObjectType="{x:Type local:StudentService}" MethodName="GetStudentList">

 

                </ObjectDataProvider>

 

                <DataTemplate x:Key="studentLayout" DataType="students">

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Path=Name}"

                            FontWeight="Bold" Foreground="Blue"/>

                        <TextBlock Text=", "></TextBlock>

                        <TextBlock Text="{Binding Path=Age}"></TextBlock>

                            <TextBlock Text=", "></TextBlock>

                            <TextBlock Text="{Binding Path=Birthday}"></TextBlock>

                              <TextBlock Text=", "></TextBlock>

                            <TextBlock Text="{Binding Path=Country}"></TextBlock>

                 

                    </StackPanel>

                </DataTemplate>

 

                <CollectionViewSource x:Key="studentsView" Source="{Binding Source={StaticResource students}}">

                    <CollectionViewSource.SortDescriptions>

                        <scm:SortDescription PropertyName="Name" Direction="Ascending" />

                        <scm:SortDescription PropertyName="Age" Direction="Descending" />

                    </CollectionViewSource.SortDescriptions>

                </CollectionViewSource>

            </StackPanel.Resources>

            <TextBlock Width="248" Height="24" Text="对象数据绑定:"

        TextWrapping="Wrap"/>

            <ListBox x:Name="listObjectBind" Width="450" Height="80" IsSynchronizedWithCurrentItem="True"

                     ItemsSource="{Binding Source={StaticResource students}}"

                     ItemTemplate="{DynamicResource studentLayout}">

 

            </ListBox>

            <TextBlock Width="248" Height="24" Text="数据排序:"

        TextWrapping="Wrap"/>

            <DataGrid DataContext="{StaticResource studentsView}" AutoGenerateColumns="False"   

                ItemsSource="{Binding}" CanUserAddRows="False">

             

                <DataGrid.Columns>

                    <DataGridTextColumn Binding="{Binding Name}" Header="名称" />

                    <DataGridTextColumn Binding="{Binding Age}" Header="年龄" />

                    <DataGridTextColumn Binding="{Binding Country}" Header="国家" />

                    <DataGridTextColumn Binding="{Binding Birthday}" Header="出生日期" />

                </DataGrid.Columns>

            </DataGrid>

        </StackPanel>


    </Grid>

   

</Window>

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

 

namespace WpfApp1.Models

{

    public class Student : DependencyObject 

    {

        //声明一个静态只读的DependencyProperty字段

        public static readonly DependencyProperty NameProperty;

        public static readonly DependencyProperty AgeProperty;

        public static readonly DependencyProperty BirthdayProperty;

        public static readonly DependencyProperty CountryProperty;

        static Student()

        {

            //注册我们定义的依赖属性Name,Age,birthday,Country

            NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student),

                new PropertyMetadata("名称", OnValueChanged));

            AgeProperty = DependencyProperty.Register("Age", typeof(string), typeof(Student),

                new PropertyMetadata("年龄", OnValueChanged));

            BirthdayProperty = DependencyProperty.Register("Birthday", typeof(string), typeof(Student),

                new PropertyMetadata("出生日期", OnValueChanged));

            CountryProperty = DependencyProperty.Register("Country", typeof(string), typeof(Student),

                new PropertyMetadata("国家", OnValueChanged));

        }

 

        private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)

        {

            //当值改变时,我们可以在此做一些逻辑处理

        }

 

        //属性包装器,通过它来读取和设置我们刚才注册的依赖属性

        public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); }

        }

        public string Age

        {

            get { return (string)GetValue(AgeProperty); }

            set { SetValue(AgeProperty, value); }

        }

 

        public string Birthday

        {

            get { return (string)GetValue(BirthdayProperty); }

            set { SetValue(BirthdayProperty, value); }

        }

 

        public string Country

        {

            get { return (string)GetValue(CountryProperty); }

            set { SetValue(CountryProperty, value); }

        }
       

    }

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using WpfApp1.Models;

 

namespace WpfApp1.Services

{

   public class StudentService

    {

       public List<Student> GetStudentList()

       {

           Student liang = new Student();

           liang.Age = "18";

           liang.Name = "梁丘";

           liang.Birthday = "1990-02-03";

           liang.Country = "中国";

           Student zuo = new Student();

           zuo.Age = "22";

           zuo.Name = "左丘";

           zuo.Birthday = "1992-02-03";

           zuo.Country = "中国";

           Student diwu = new Student();

           diwu.Age = "32";

           diwu.Name = "第五言";

           diwu.Birthday = "1982-11-03";

           diwu.Country = "中国";

           Student yang = new Student();

           yang.Age = "12";

           yang.Name = "羊舌微";

           yang.Birthday = "2002-11-13";

           yang.Country = "中国";

           List<Student> personList = new List<Student>();

           personList.Add(liang);

           personList.Add(zuo);

           personList.Add(diwu);

           personList.Add(yang);

           return personList;

       }

 

    }

}

 
更多相关文章
  • WPF入门教程系列十五——WPF中的数据绑定(一)
       使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面,同时 WPF提供了数据绑定功能.WPF的数据绑定跟Winform与ASP.NET中的数据绑定功能类似,但也有所不同,在 WPF中以通过后台代码绑定.前台XAML中进行绑定,或者两者 ...
  • WPF入门教程系列十六——WPF中的数据绑定(二)
    三.绑定模式     通过上一文章中的示例,学习了简单的绑定方式.在这里的示例,要学习一下绑定的模式,和模式的使用效果.     首先,我们来做一个简单示例,这个示例是根据ListBox中的选中项,去改变TextBlock的背景色.将 TextBlock 的背景色绑定到在 ListBox 中选择的颜 ...
  • WPF入门教程系列十九——ListView示例(一)
         经过前面的学习,今天我做一个比较综合的WPF程序示例,主要包括以下功能:  1) 查询功能.从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,然后展示到WPF的Window上的一个ListView上. 2) 数据联动功能.当鼠标左键选中ListView中的某 ...
  • WPF入门教程系列十二——依赖属性二
    二. 依赖属性的优先级 由于WPF 允许我们可以在多个地方设置依赖属性的值,所以我们就必须要用一个标准来保证值的优先级别.比如下面的例子中,我们在三个地方设置了按钮的背景颜色,那么哪一个设置才会是最终的结果呢?是Black.Red还是Azure呢? <Window x:Class=" ...
  • WPF入门教程系列十——布局之Border与ViewBox五
    九. Border Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel 控件放置在父 Border 中.然后可以将子控件放置在该 Panel控件中. Border 的几个重要属性: Background:用用一 ...
  • WPF入门教程系列九——布局之DockPanel与ViewBox四
    七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中.停靠面板其实就是在WinForm类似于Dock属性的元 素.DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序. ...
  • WPF入门教程系列二十三——DataGrid示例(三)
    DataGrid的选择模式    默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改DataGrid 的选择模式.   SelectionUnit的选择模式. 成员名称 说明 C ...
  • WPF入门教程系列二——Application介绍
    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只有一个 Application 实例存在.和 WinForm 不同的是WPF Application ...
一周排行