【WPF學習】第二十三章 列表控制項

来源:https://www.cnblogs.com/Peter-Luo/archive/2020/02/03/12254951.html
-Advertisement-
Play Games

WPF提供了許多封裝項的集合的控制項,本章介紹簡單的ListBox和ComboBox控制項,後續哈會介紹更特殊的控制項,如ListView、TreeView和ToolBar控制項。所有這些控制項都繼承自ItemsControl類(ItemsControl類本身又繼承自Control類)。 ItemsContr ...


  WPF提供了許多封裝項的集合的控制項,本章介紹簡單的ListBox和ComboBox控制項,後續哈會介紹更特殊的控制項,如ListView、TreeView和ToolBar控制項。所有這些控制項都繼承自ItemsControl類(ItemsControl類本身又繼承自Control類)。

  ItemsControl類添加了所有基於列表的控制項都使用的基本功能。最顯著的是,它提供了填充列表項的兩種方式。最直接的方法是代碼或XAML將列表項直接添加到Items集合中。然而,在WPF中使用數據綁定的方法更普遍。使用數據綁定方法,需將ItemsSource屬性設置為希望顯示的具有數據項集合的對象(後續章節介紹與列表數據綁定相關的更多內容)。

  ItemsControl類之後的繼承橙子有些混亂。一個主要分支是選擇器(selector),包括ListBox、ComboBox以及TabControl。這些控制項都繼承自Selector類,並且都具有跟蹤當前選擇項(SelectedItem)或其位置(SelectedIndex)的屬性,封裝列表項的控制項是另一個分支,以不同方式選擇列表項。該分支包括用於菜單、工具欄以及樹的類——所有這些類都屬於ItemsControl,但不是選擇器。

  為了充分發揮所有ItemsControl控制項的功能,需要使用數據綁定。即使不從資料庫甚至外部數據源獲取數據,也同樣如此。WPF數據綁定非常普遍,可使用各種數據,包括自定義的數據對象和集合。但現在還不需要考慮數據綁定的細節。現在,先快速瀏覽一下ListBox控制項和ComboBox控制項。

一、ListBox

  ListBox類代表了一種最常用的Windows設計——允許用戶從長度可變的列表中選擇一項。

  如果將SelectionMode屬性設置為Multiple或Extended,ListBox類還允許選擇多項。在Multiple模式下,可通過單擊項進行選擇或取消選擇。在Extended模式下,需要按下Ctrl鍵選擇其他項,或按下Shift鍵選擇某個選項範圍。在這兩種多選模式下,可用SelectedItems集合替代SelectedItem屬性來獲取所有選擇的項。

  為向ListBox控制項中添加項,可在ListBox元素中嵌套ListBoxItem元素。例如,下麵是一個包含顏色列表的ListBox:

<ListBox>
     <ListBoxItem>Yellow</ListBoxItem>
     <ListBoxItem>Blue</ListBoxItem>
     <ListBoxItem>Green</ListBoxItem>
     <ListBoxItem>Red</ListBoxItem>
     <ListBoxItem>LightBlue</ListBoxItem>
     <ListBoxItem>Black</ListBoxItem>
</ListBox>

  不同控制項採用不同方式處理嵌套的內容。ListBox控制項在它的Items集合中存儲每個嵌套的對象。

  ListBox控制項是一個非常靈活的控制項。它不僅可以包含ListBoxItem對象,也可以駐留其他任意元素。這是因為ListBoxItem類繼承自ContentControl類,從而ListBoxItem能夠包含一段嵌套的內容。如果該內容繼承自UIElement類,它將ListBox控制項中呈現出來。如果是其他類型的對象,ListBoxItem對象會調用ToString()方法並顯示最終的文本。

  例如,如果決定創建一個包含圖像的列表,可使用如下標記:

<ListBox>
        <ListBoxItem>
            <Image Source="happyface.jpg"></Image>
        </ListBoxItem>
        <ListBoxItem>
            <Image Source="redx.jpg"></Image>
        </ListBoxItem>
</ListBox>

  實際上ListBox控制項足夠職能,它能隱式地創建所需的ListBoxItem對象。這意味著可直接在ListBox元素中放置對象。廈門市一個更複雜的示例,該示例使用嵌套的StackPanel對象組合文本和圖像內容:

<Window x:Class="Controls.ImageList"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ImageList" Height="300" Width="300">
    <ListBox Margin="5" SelectionMode="Multiple" Name="lst" SelectionChanged="lst_SelectionChanged">
        <StackPanel Orientation="Horizontal">
            <Image Source="happyface.jpg" Width="30" Height="30"></Image>
            <Label VerticalAlignment="Center">A Happy face</Label>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Source="redx.jpg" Width="30" Height="30"></Image>
            <Label VerticalAlignment="Center">A Warning face</Label>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Source="happyface.jpg" Width="30" Height="30"></Image>
            <Label VerticalAlignment="Center">A Happy face</Label>
        </StackPanel>
    </ListBox>
</Window>
ImageListBox

  在該例中,StackPanel面板變成被ListBoxItem封裝的項。該標記創建的富列表如圖下圖所示:

 

   利用在列表框中的嵌套任意元素的能力,可創建出各種基於列表的控制項,而不必使用其他類。例如,Windows窗體的哦該凝聚項中CheckedListBox類,該類顯示在每個項的旁邊都具有覆選框的列表。在WPF中不需要這一特殊類,因為完全可使用標準的ListBox控制項快速構建相同的效果:

<Window x:Class="Controls.CheckBoxList"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CheckBoxList" Height="300" Width="300">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <ListBox Name="lst" SelectionChanged="lst_SelectionChanged"
             CheckBox.Click="lst_SelectionChanged" >
            <CheckBox Margin="3">Option 1</CheckBox>
            <CheckBox Margin="3">Option 2</CheckBox>
            <CheckBox Margin="3">Option 3</CheckBox>
        </ListBox>
        <StackPanel Grid.Row="1" Margin="0,10,0,0">
            <TextBlock>Current selection:</TextBlock>
            <TextBlock  Name="txtSelection" TextWrapping="Wrap"></TextBlock>
            <Button Margin="0,10,0,0" Click="cmd_CheckAllItems">Examine All Items</Button>
        </StackPanel>
    </Grid>
</Window>
CheckBoxList

  當在列表內部使用不同元素時需要註意一點。當讀取SelectedItem值時(以及SelectedItems和Items集合),看不到ListBoxItem對象——反而將看到放入到列表中的對象。在CheckedListBox示例中,這意味著SelectedItem提供了CheckBox對象。

  例如,下麵是一些響應SelectionChanged事件觸發的代碼。這些代碼獲取當天選中CheckBox對象並顯示該項是否被選中:

private void lst_SelectionChanged(object sender, RoutedEventArgs e)
        {
            // Select when checkbox portion is clicked (optional).
            if (e.OriginalSource is CheckBox)
            {
                lst.SelectedItem = e.OriginalSource;
            }

            if (lst.SelectedItem == null) return;
            txtSelection.Text = String.Format(
                "You chose item at position {0}.\r\nChecked state is {1}.",
                lst.SelectedIndex,
                ((CheckBox)lst.SelectedItem).IsChecked);
        }

  在下麵的代碼片段中,類似的代碼遍歷選項集合以確定哪一項被選中(對於使用覆選框的多項選擇列表,可以編寫類似的代碼來遍歷選中項的集合)。

private void cmd_CheckAllItems(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (CheckBox item in lst.Items)
            {
                if (item.IsChecked == true)
                {
                    sb.Append(
                        item.Content + " is checked.");
                    sb.Append("\r\n");
                }
            }
            txtSelection.Text = sb.ToString();
        }

  最終效果如下所示:

 

   在列表框中手動放置項時,由你決定是希望直接插入項還是在ListBoxItem對象中明確地包含每項。第二種方法通常更清晰,也更繁瑣。最重要的考慮事項是一致性。例如,如果在列表中放置StackPanel對象,ListBox.SelectedItem對象將是StackPanel。如果放置由ListBoxItem對象封裝的StackPanel對象,ListBox.SelectedItem對象將是ListBoxItem,所以可進行響應編碼。

  ListBoxItem提供了少許額外功能,通過這些功能可得到直接嵌套的對象。換言之,ListBoxItem定義了可以讀取(或設置)的IsSelected屬性,以及用於通知何時選中的Selected和Unselected事件。然而,可使用ListBox類的成員得到類似功能,如SelectedItem屬性(或SelectedItems屬性)以及SelectionChanged事件。

  有趣的是,當使用嵌套對象方法時,有一項技術可為特定的對象檢索ListBoxItem封裝器。技巧是使用常被忽視的ContainerFromElement()方法。下麵的代碼使用該技術檢查列表中的第一個條目是否被選中:

ListBoxItem item=(ListBoxItem)lst.ContainerFromElement((DependencyObject)lst.SelectedItems[0]);
MessageBox.Show("IsSelected:"+item.IsSelected.ToString());

二、ComboBox

  ComboBox控制項和ListBox控制項類似。該控制項包含ComboBoxItem對象的集合,既可以顯示地也可以隱式地創建該集合。與ListBoxItem類似,ComboBoxItem也是可以包含任意嵌套元素的內容控制項。

  ComboBox類和ListBox類之間的重要區別是他們在視窗中呈現自身的方式。Combox控制項使用下拉列表,這意味著一次只能選擇一項。

  如果希望允許用戶在組合框中通過輸入文本選項一項,就必須將IsEditable屬性設置為true,並且必須確保選項集合中存儲的是普遍的純文本的ComboBoxItem對象,或是提供了有意義的ToString()表示的對象。例如,如果使用Image對象填充可編輯的組合框,那麼在上面顯示的文本將只有Image類的全名,這用處不大。

  ComboBox控制項的局限之一在於當使用自動改變尺寸功能時該控制項改變自身尺寸的方法。ComboBox控制項加寬自身以適應它的內容,這意味著當從一項移到另一項是它會改變自身大小。但沒有簡便的方法告訴ComboBox控制項使用包含項的最大尺寸。相反,需要為Width屬性提供硬編碼的值,而這並不理想。

下麵是一個簡單的示例:

<Window x:Class="Controls.ComboBoxTest"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxTest" Height="300" Width="300">
    <StackPanel>
        <ComboBox Margin="5">
            <StackPanel Orientation="Horizontal">
                <Image Source="happyface.jpg" Width="30" Height="30"></Image>
                <Label VerticalAlignment="Center">A Happy face</Label>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Image Source="redx.jpg" Width="30" Height="30"></Image>
                <Label VerticalAlignment="Center">A Warning face</Label>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Image Source="happyface.jpg" Width="30" Height="30"></Image>
                <Label VerticalAlignment="Center">A Happy face</Label>
            </StackPanel>
        </ComboBox>
    </StackPanel>
</Window>
ComboBoxTest

  最終效果圖如下所示:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇文章主要講解實現線程的方式到底有幾種?以及實現 Runnable 介面究竟比繼承 Thread 類實現線程好在哪裡? 實現線程是併發編程中基礎中的基礎,因為我們必須要先實現多線程,才可以繼續後續的一系列操作。所以本文就先從併發編程的基礎如何實現線程開始講起。 實現線程的方式到底有幾種?我們接下來 ...
  • 簡介 Python是一種跨平臺的電腦程式設計語言。是一種面向對象的動態類型語言,最初被設計用於編寫自動化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越多被用於獨立的、大型項目的開發。 Anaconda 是一個基於 Python 的數據處理和科學計算平臺,它已經內置了許多非常有用的第三 ...
  • 大綱 一.什麼是Hash?什麼是HashMap? 二.HashMap的內部實現機制 1.HashMap基本元素 ①DEFAULT_INITIAL_CAPACITY&MAXIMUM_CAPACITY ②DEFAULT_LOAD_FACTOR&loadFactor ③size&threshold 2.H ...
  • th:href="@{/static/css/style.css}" th:src="@{/static/js/thymeleaf.js}" index.html <head> <meta charset="UTF-8"> <title>首頁</title> <link rel="styleshee ...
  • 網上的教程大都是手動通過protoc編譯, 比較難用 給當前工程添加"Google.Protobuf"和"Grpc.Tools"的引用(通過nuget), 然後添加proto文件, 編輯.csproj文件 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGrou ...
  • 微信公眾號: "Dotnet9" ,網站: "Dotnet9" ,問題或建議: "請網站留言" , 如果對您有所幫助: "歡迎贊賞" 。 閱讀導航 1. 本文背景 2. 代碼實現 3. 本文參考 4. 源碼 1. 本文背景 同上篇文章《少量代碼設計一個登錄界面》,本篇介紹另一種登錄界面設計風格。 2 ...
  • 這是在ASP.NET Core 3.X中使用Serilog.AspNetCore系列文章的第四篇文章:。 1. "第1部分 使用Serilog RequestLogging減少日誌詳細程度" 2. "第2部分 使用Serilog記錄所選的終結點屬性" 3. "第3部分 使用Serilog.AspN ...
  • 實例2.1 通過控制台實現對Excel的自動化處理 書本第32頁 註:添加兩個引用: 第一個:程式集—框架—“System.Windows.Forms 4.0.0.0”第二個:程式集—擴展—“Microsoft.Office.Interop.Excel 14.0.0.0” 程式清單2.1通過控制台程 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...