有关ListBox

如何拿到Source:从SQL,从XML file

SQL:一个是ObjectDataProvider

//用linq方法拿到SQL data,wrap到一个IEnumerable<Customer>

public IEnumerable<Customer> GetAllCustomersAsList()
    {
      var items = from cust in this.Customers
                  orderby cust.LastName
                  select cust;

      return items.ToList();
    }
View Code
//xaml里定义ObjectDataProvider 拿到这个Customer list resource

 <ObjectDataProvider x:Key="odpCust"
                        ObjectType="{x:Type
         src:AdvWorksDataContext}"
                        MethodName="GetTable">
      <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="src:Customer" />
      </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>
View Code
//消费

<ListBox ItemsSource="{Binding 
        Source={StaticResource odpCust}}"
             DisplayMemberPath="LastName"></ListBox>
View Code

 

XML file:一个是XmlDataProvider

//准备XML文件

<?xml version="1.0" standalone="yes"?>
<Products>
  <Product>
    <ProductId>1</ProductId>
    <ProductName>PDSA .NET Productivity Framework V4.1</ProductName>
    <Price>5000</Price>
    <Logo>/Images/Framework.gif</Logo>
  </Product>
  <Product>
    <ProductId>2</ProductId>
    <ProductName>Architecting ASP.NET Applications eBook</ProductName>
    <Price>19.95</Price>
    <Logo>/Images/ArchASPNET_100.gif</Logo>
  </Product>
  <Product>
    <ProductId>3</ProductId>
    <ProductName>Fundamentals of N-Tier eBook</ProductName>
    <Price>19.95</Price>
    <Logo>/Images/FundNTier_100.gif</Logo>
  </Product>
  <Product>
    <ProductId>4</ProductId>
    <ProductName>Security for ASP.NET Developers eBook</ProductName>
    <Price>19.95</Price>
    <Logo>/Images/FundSecurity_100.gif</Logo>
  </Product>
  <Product>
    <ProductId>6</ProductId>
    <ProductName>VB.NET Fundamentals eBook</ProductName>
    <Price>19.95</Price>
    <Logo>/Images/FundVBNet_100.gif</Logo>
  </Product>
  <Product>
    <ProductId>7</ProductId>
    <ProductName>Fundamentals of SQL Server 2005</ProductName>
    <Price>19.95</Price>
    <Logo>/Images/FundSQL_100.gif</Logo>
  </Product>
</Products>
View Code
//准备XML应用的资源
<XmlDataProvider x:Key="xmlProducts"
                     Source="/Xml/Product.xml"
                     XPath="Products/Product"></XmlDataProvider>
View Code
//消费XmlDataProvider

<ListBox Name="lstProducts"
             ItemsSource="{Binding Source={StaticResource xmlProducts}}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal">
            <Image Margin="8"
                   Source="{Binding XPath=Logo}"
                   Width="100"></Image>
            <Label Width="250"
                   Content="{Binding XPath=ProductName}"></Label>
            <Label Width="100"
                   Content="{Binding XPath=Price}"></Label>
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
View Code

 

Assign Template in xaml & Dynamic change Template in Code

 

//后台方法定义

 public IOrderedQueryable<Customer> GetAllCustomers()
    {
      var items = from cust in this.Customers
                  orderby cust.LastName
                  select cust;

      return items;
    }
View Code

 

//prepare different layout DT

<Window.Resources>
    <ObjectDataProvider x:Key="odpCust"
                        ObjectType="{x:Type src:AdvWorksDataContext}"
                        MethodName="GetAllCustomers"></ObjectDataProvider>
    <Style TargetType="Button">
      <Setter Property="Margin"
              Value="8"></Setter>
      <Setter Property="Width"
              Value="60"></Setter>
    </Style>
    <DataTemplate x:Key="tmplMore">
      <StackPanel Orientation="Vertical"
                  HorizontalAlignment="Left"
                  Margin="8">
        <StackPanel Orientation="Horizontal">
          <Label FontSize="16"
                 Content="{Binding Path=FirstName}"></Label>
          <Label Width="Auto"
                 FontSize="16"
                 Content="{Binding Path=LastName}"></Label>
        </StackPanel>
        <Label FontSize="12"
               Content="{Binding Path=EmailAddress}"></Label>        
      </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="tmplLess">
      <StackPanel Orientation="Vertical"
                  HorizontalAlignment="Left"
                  Margin="8">
        <StackPanel Orientation="Horizontal">
          <Label FontSize="16"
                 Content="{Binding Path=FirstName}"></Label>
          <Label Width="Auto"
                 FontSize="16"
                 Content="{Binding Path=LastName}"></Label>
        </StackPanel>
      </StackPanel>
    </DataTemplate>
  </Window.Resources>
View Code
//消费ObjectDataProvider和DT
//一个是ItemsSource一个是ItemTemplate

<ListBox Margin="10,10,0,0"
               Height="300"
               Name="lstData"
               ItemsSource="{Binding Source={StaticResource odpCust}}"
               IsSynchronizedWithCurrentItem="True"
               ItemTemplate="{StaticResource tmplMore}">
      </ListBox>
View Code

后台程序 runtime change DT:

//lstData可以找前台的x:name,FindResource可以找前台的x:key

public partial class frmListBox2Templates : Window
  {
    public frmListBox2Templates()
    {
      InitializeComponent();
    }

    private void btnMore_Click(object sender, RoutedEventArgs e)
    {
      DataTemplate tmpl;

      tmpl = (DataTemplate)this.FindResource("tmplMore");
      if(tmpl != null)
        lstData.ItemTemplate = tmpl;
    }

    private void btnLess_Click(object sender, RoutedEventArgs e)
    {
      DataTemplate tmpl;

      tmpl = (DataTemplate)this.FindResource("tmplLess");
      if (tmpl != null)
        lstData.ItemTemplate = tmpl;
    }
  }
View Code

 

ListBox Sorting and Filter:

首先need datasource coming back from IEnumerable<T>

use CollectionViewSource

然后才可以sort或者filter,sort可以xaml或者code,但是filter要code

 

xaml sort的例子

 

//后台程序
//Customers是GetAllCustomersAsList的一个Table
//items.ToList()是因为我们要sort这个listbox,.list给了很好的支持

public IEnumerable<Customer> GetAllCustomersAsList()
    {
      var items = from cust in this.Customers 
                  orderby cust.LastName
                  select cust;

      return items.ToList();
    }
View Code

 

//ObjectDataProvider连接后台GetAllCustomersAsList返回一个可以sort的customers list
//CollectionViewSource 提供了sort的一切功能,可以set CollectionViewSource.SortDescriptions
//注意SortDescription 前面要加scm
//可以有多个SortDescription 

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


<Window.Resources>
    <ObjectDataProvider x:Key="odpCust"
                        ObjectType="{x:Type src:AdvWorksDataContext}"
                        MethodName="GetAllCustomersAsList">
    </ObjectDataProvider>
    <CollectionViewSource Source="{StaticResource odpCust}"
                          x:Key="collCust">
      <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="LastName" Direction="Ascending" />
        <scm:SortDescription PropertyName="FirstName" Direction="Ascending" />
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
  </Window.Resources>            
View Code

coding sort的例子(两个button用来sort)

//resources里不用定义CollectionViewSource了

<Window.Resources>
    <ObjectDataProvider x:Key="odpCust"
                        ObjectType="{x:Type src:AdvWorksDataContext}"                       
                        MethodName="GetAllCustomersAsList"></ObjectDataProvider>
  </Window.Resources>
View Code
//ItemSource属性消费ObjectDataProvider,注意这里要可以sort ItemsSource must use the ToList()
//两个RadioButton的Tag是重点


<Grid>
    <StackPanel>
      <GroupBox Header="Sorting Options" BorderBrush="Black" BorderThickness="1">
        <StackPanel Orientation="Horizontal">
          <RadioButton Name="rdoSortLast"
                       Margin="8"
                       Tag="LastName"
                       IsChecked="True"
                       Checked="SortTheData">Sort by Last Name</RadioButton>
          <RadioButton Name="rdoSortFirst"
                    Margin="8"
                       Tag="FirstName"
                    Checked="SortTheData">Sort by First Name</RadioButton>
        </StackPanel>
      </GroupBox>
      <Label FontSize="16">Customers</Label>
      <ListBox Name="lstCustomers"
               Height="300"
               ItemsSource="{Binding Source={StaticResource odpCust}}">
        <!-- ItemTemplate controls the data within each item in the ListBox -->
        <ListBox.ItemTemplate>
          <DataTemplate>
            <StackPanel Orientation="Vertical"
                        HorizontalAlignment="Left"
                        Margin="8">
              <StackPanel Orientation="Horizontal">
                <Label FontSize="16"
                       Content="{Binding Path=FirstName}"></Label>
                <Label Width="Auto"
                       FontSize="16"
                       Content="{Binding Path=LastName}"></Label>
              </StackPanel>
              <Label FontSize="12"
                     Content="{Binding Path=EmailAddress}"></Label>
            </StackPanel>
          </DataTemplate>
        </ListBox.ItemTemplate>
      </ListBox>
    </StackPanel>
  </Grid>
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using WPFComponents;
using System.ComponentModel;

namespace WPFListBox
{
  /// <summary>
  /// Interaction logic for frmListBoxSortUsingCode.xaml
  /// </summary>
  public partial class frmListBoxSortUsingCode : Window
  {
    public frmListBoxSortUsingCode()
    {
      InitializeComponent();
    }

    private void SortTheData(object sender, RoutedEventArgs e)
    {
      // For sorting to work, the ItemsSource must use the ToList()
      if (lstCustomers != null)
      {
        ICollectionView dataView =
            CollectionViewSource.GetDefaultView( 
              lstCustomers.ItemsSource);

        dataView.SortDescriptions.Clear();
        dataView.SortDescriptions.Add(
            new SortDescription(
                (sender as RadioButton).Tag.ToString(),
                      ListSortDirection.Ascending));

        lstCustomers.ItemsSource = dataView;
      }
    }
  }
}
View Code

 

code filter的例子

Filter boxlist,以Texbox里写入的字符串filter

Filter部分的代码,按查找按钮调用FilterData
//=>linq的写法,cust是parameter,返回这个parameter,其是grab customer类型的对象,看他的LastName.ToLower()是否以TextBox里写的字符小写为开始的

private void FilterData()
    {
      // For Filtering to work, the ItemsSource must use the ToList()
      // It must be IEnumerable<Customer>
      if (lstCustomers != null)
      {
        ICollectionView dataView =
            CollectionViewSource.GetDefaultView(
               lstCustomers.ItemsSource);

        dataView.Filter = cust =>
           ((Customer)cust).LastName.ToLower().
             StartsWith(txtLast.Text.ToLower());

        lstCustomers.ItemsSource = dataView;
      }
    }
View Code

 

 ListBox里项目的Converter:从xml里拿到的item是一个xml对象,我们需要让其变成decimal然后format成C(currency:$)

 

//还是用XmlDataProvider compile xml data
//注意是Label,用的是Content所以format要用ContentStringFormat而不是StringFormat
//ContentStringFormat="{}{0:C}"这里的第一个{}是escape后面的{0:C},表示{0:C}整个看作一个string写入
//C表示format成currency但是前提是要对的type(decimal)


<Window x:Class="WPFListBox.frmListBoxFormatConverter"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:WPFComponents;assembly=WPFComponents"
        Title="List Box Formatting using ValueConverter"
        WindowStartupLocation="CenterScreen"
        Height="390"
        Width="682">
  <Window.Resources>
    <src:XmlElementToDecimalConverter x:Key="sdConvert" />
    <XmlDataProvider x:Key="xmlProducts"
                     Source="/Xml/Product.xml"
                     XPath="Products/Product"></XmlDataProvider>
  </Window.Resources>
  <Grid>
    <ListBox Name="lstProducts"
             ItemsSource="{Binding Source={StaticResource xmlProducts}}"
             IsSynchronizedWithCurrentItem="True">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal">
            <Image Margin="8" Source="{Binding XPath=Logo}"
                   Width="100"></Image>
            <Label Width="250"
                   Content="{Binding XPath=ProductName}"></Label>
            <Label Width="100" ContentStringFormat="{}{0:C}"
                   Content="{Binding XPath=Price, 
                   Converter={StaticResource sdConvert}}"></Label>
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </Grid>
</Window>
View Code
//看attibute,代表Convert方法,进去的是XmlElement出的是decimal


using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;
using System.Xml;

namespace WPFComponents
{
  [ValueConversion(typeof(XmlElement), typeof(decimal))]
  public class XmlElementToDecimalConverter : IValueConverter
  {
    public object Convert(object value, Type targetType,
                                        object parameter, CultureInfo culture)
    {
      return System.Convert.ToDecimal(((XmlElement)value).InnerText);
    }

    public object ConvertBack(object value, Type targetType, 
                                                object parameter, CultureInfo culture)
    {
      return System.Convert.ToString(value);
    }
  }
}
View Code

 

 

posted @ 2013-09-19 13:44  若愚Shawn  阅读(246)  评论(0编辑  收藏  举报