欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WPF實(shí)現(xiàn)帶全選復(fù)選框的列表控件

 更新時(shí)間:2017年06月22日 14:54:38   作者:WPInfo  
這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)帶全選復(fù)選框的列表控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文將說明如何創(chuàng)建一個(gè)帶全選復(fù)選框的列表控件。其效果如下圖:


這個(gè)控件是由一個(gè)復(fù)選框(CheckBox)與一個(gè) ListView 組合而成。它的操作邏輯:

  • 當(dāng)選中“全選”時(shí),列表中所有的項(xiàng)目都會(huì)被選中;反之,取消選中“全選”時(shí),所有項(xiàng)都會(huì)被取消勾選。
  • 在列表中選中部分?jǐn)?shù)據(jù)項(xiàng)目時(shí),“全選”框會(huì)呈現(xiàn)不確定狀態(tài)(Indetermine)。

由此看出,“全選”復(fù)選框與列表項(xiàng)中的復(fù)選框達(dá)到了雙向控制的效果。

其設(shè)計(jì)思路:首先,創(chuàng)建自定義控件(CheckListView),在其 ControlTemplate 中定義 CheckBox 和 ListView,并為 ListView 設(shè)置 ItemTemplate,在其中增加 CheckBox 控件,如下:

<ControlTemplate TargetType="{x:Type control:CheckListView}">
          <Grid Background="{TemplateBinding Background}">
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            
            <CheckBox Content="全選" />            
            
            <ListView x:Name="list"
                 Grid.Row="1">
              <ListView.ItemTemplate>
                <DataTemplate>
                  <CheckBox />                  
                </DataTemplate>
              </ListView.ItemTemplate>
            </ListView>
          </Grid>
        </ControlTemplate>

其次,為控件添加兩個(gè)依賴屬性,其中一個(gè)為 ItemsSource,即該控件所要接收的數(shù)據(jù)源,也即選擇列表;本質(zhì)上,這個(gè)數(shù)據(jù)源會(huì)指定給其內(nèi)的 ListView。另外也需要一個(gè)屬性 IsSelectAllChecked 表示是否選中全選復(fù)選框。

public static readonly DependencyProperty IsSelectAllCheckedProperty =
      DependencyProperty.Register("IsSelectAllChecked", typeof(bool?), typeof(CheckListView), new PropertyMetadata(false));

    public static readonly DependencyProperty ItemsSourceProperty =
      DependencyProperty.Register("ItemsSource", typeof(object), typeof(CheckListView), new PropertyMetadata(null));

    /// <summary>
    /// 返回或設(shè)置全選復(fù)選框的選中狀態(tài)
    /// </summary>
    public bool? IsSelectAllChecked
    {
      get { return (bool?)GetValue(IsSelectAllCheckedProperty); }
      set { SetValue(IsSelectAllCheckedProperty, value); }
    }

    /// <summary>
    /// 數(shù)據(jù)源
    /// </summary>
    public object ItemsSource
    {
      get { return (object)GetValue(ItemsSourceProperty); }
      set { SetValue(ItemsSourceProperty, value); }
    } 

需要注意的一點(diǎn)是,作為一個(gè)自定義控件,我們必須考慮它的通用性,所以為了保證能設(shè)置各式各樣的數(shù)據(jù)源(如用戶列表、物品列表或 XX名稱列表),在這里定義一個(gè)數(shù)據(jù)接口,只要數(shù)據(jù)源中的數(shù)據(jù)項(xiàng)實(shí)現(xiàn)該接口,即可達(dá)到通用的效果。該接口定義如下:

public interface ICheckItem
  {
    /// <summary>
    /// 當(dāng)前項(xiàng)是否選中
    /// </summary>
    bool IsSelected { get; set; }

    /// <summary>
    /// 名稱
    /// </summary>
    string Name { get; set; }
  }

最后,我們把剛才定的屬性綁定的控件上,如下:

<CheckBox Content="全選" IsChecked="{Binding IsSelectAllChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
 <ListView x:Name="list" Grid.Row="1" ItemsSource="{TemplateBinding ItemsSource}">
   <ListView.ItemTemplate>
    <DataTemplate>
        <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
          </DataTemplate>
        </ListView.ItemTemplate>
</ListView>

接下來,實(shí)現(xiàn)具體操作:

首先,通過“全選”復(fù)選框來控制所有列表項(xiàng):這里通過其 Click 事件來執(zhí)行 CheckAllItems 方法, 在此方法中,會(huì)對(duì)數(shù)據(jù)源進(jìn)行遍歷,將其 IsSelected 屬性設(shè)置為 True 或 False。代碼如下:

<CheckBox Content="全選" IsChecked="{Binding IsSelectAllChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
      <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
           <ei:CallMethodAction MethodName="CheckAllItems" TargetObject="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
         </i:EventTrigger>
        </i:Interaction.Triggers>
 </CheckBox>
/// <summary>
/// 全選或清空所用選擇
/// </summary>
    public void CheckAllItems()
    {
      foreach (ICheckItem item in ItemsSource as IList<ICheckItem>)
      {
        item.IsSelected = IsSelectAllChecked.HasValue ? IsSelectAllChecked.Value : false;
      }
    }

然后,通過選中或取消選中列表項(xiàng)時(shí),更新“全選”復(fù)選框的狀態(tài):在 DataTemplate 中,我們也為 CheckBox 的 Click 事件設(shè)置了要觸發(fā)的方法 UpdateSelectAllState,代碼如下:

<DataTemplate>
   <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}">
     <i:Interaction.Triggers>
     <i:EventTrigger EventName="Click">
      <ei:CallMethodAction MethodName="UpdateSelectAllState" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=control:CheckListView}}" />
     </i:EventTrigger>
     </i:Interaction.Triggers>
  </CheckBox>
</DataTemplate>
/// <summary>
/// 根據(jù)當(dāng)前選擇的個(gè)數(shù)來更新全選框的狀態(tài)
/// </summary>
    public void UpdateSelectAllState()
    {
      var items = ItemsSource as IList<ICheckItem>;
      if (items == null)
      {
        return;
      }

      // 獲取列表項(xiàng)中 IsSelected 值為 True 的個(gè)數(shù),并通過該值來確定 IsSelectAllChecked 的值
      int count = items.Where(item => item.IsSelected).Count();
      if (count == items.Count)
      {
        IsSelectAllChecked = true;
      }
      else if (count == 0)
      {
        IsSelectAllChecked = false;
      }
      else
      {        
        IsSelectAllChecked = null;
      }
    }


這里也有兩點(diǎn)需要提醒:

我一開始定義屬性 IsSelectAllChecked 時(shí),它的類型是 bool 類型,那么,由于 CheckBox 控件的 IsChecked 值為 null 時(shí),它將呈現(xiàn) Indetermine 狀態(tài),所以后來把它改為 bool? 類型。

在XAML 代碼中可以看出,對(duì)事件以及事件的響應(yīng)使用了行為,所以,需要添加引用 System.Windows.Interactivity.dll 和 Microsoft.Expression.Interactions.dll 兩個(gè)庫(kù),并在XMAL 頭部添加如下命名空間的引用:

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

這樣,這個(gè)控件就基本完成了,接下來是如何使用它。

首先,定義將要在列表中展示的數(shù)據(jù)項(xiàng),并為它實(shí)現(xiàn)之前提到的 ICheckItem 接口,這里定義了一個(gè) User 類,如下:

public class User : BindableBase, ICheckItem
  {
    private bool isSelected;
    private string name;

    public bool IsSelected
    {
      get { return isSelected; }
      set { SetProperty(ref isSelected, value); }
    }

    public string Name
    {
      get { return name; }
      set { SetProperty(ref name, value); }
    }
  }

接下來在 ViewModel 中定義一個(gè)列表 List<ICheckItem>,并添加數(shù)據(jù),最后在 UI 上為其綁定 ItemsSource 屬性即可,在此不再貼代碼了,具體請(qǐng)參考源代碼。

源碼下載

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論