思路:大項目的每項中包含一個小項目集合,用ListBox嵌套ListBox或ListBox嵌套ItemsCtrol是個比較好的方式,現總結如下:
第一:先構建題目類,再建一個選項類,題目類集合中的每個項包含一個選項類集合,即數組嵌套數組,C#語句如下:
(為方便看清語句,類直接寫在主程序中)
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.Navigation; using System.Windows.Shapes; using System.Collections.ObjectModel;//ObservableCollection命名空間 namespace ListBoxInListBox { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //題目類 class question { public string qutestionName//題目名,比如:第1題或第2題等 { get; set; } public ObservableCollection<choseItem> choseItems//某題中"選項類"的集合,比如A-D { get; set; } public question(string _questionname, ObservableCollection<choseItem> _choseitems)//構造函數 { qutestionName = _questionname; choseItems = _choseitems; } } //選項類 class choseItem { public string ChoseName//選項名,比如:A,B,C,D之類 { get; set; } public string ChoseContent//選項內容 { get; set; } } ObservableCollection<question> Questions = new ObservableCollection<question>();//題目數組 private void Window_Loaded(object sender, RoutedEventArgs e) { string[] CharStr = new string[4] { "A", "B", "C", "D" }; for (int i = 0; i < 5; i++) { ObservableCollection<choseItem> ChoseItems = new ObservableCollection<choseItem>();//選項數組 for (int j = 0; j < 4; j++) { choseItem item = new choseItem();//選項類 item.ChoseName = CharStr[j] + ":"; item.ChoseContent = "選項內容"; ChoseItems.Add(item); } Questions.Add(new question("__第" + (i + 1).ToString() + "題", ChoseItems)); } listbox1.ItemsSource = Questions; } } }
第二步:主界面的綁定語句如下:
<Window x:Class="ListBoxInListBox.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ListBox嵌套ListBox測試" Height="350" Width="525" Loaded="Window_Loaded"> <Window.Resources > <!--第一部分:內嵌的ListBox用什么布局--> <ItemsPanelTemplate x:Key="itemspanel"> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" /> </ItemsPanelTemplate> <!-- 第二部分:內嵌ListBox的項模板--> <DataTemplate x:Key="itemstemplate"> <!-- 用Canvas來裝可以精確定位項,但沒有水平滾動條Canvas.Left="{Binding Path=LeftWidth}" Canvas.Top="0" 只好用StackPanel來布局--> <StackPanel Orientation="Vertical" > <Border BorderBrush="Blue" BorderThickness="1" CornerRadius="3" > <StackPanel Orientation="Horizontal" Margin="5,0,5,0"> <!-- 這里是裝項內容--> <Image Source="/zero.png" Width="32" Height="32" /> <TextBlock Text="{Binding Path=ChoseName}" VerticalAlignment="Center" Margin="2" /> <TextBox Text="{Binding Path=ChoseContent}" IsReadOnly="True" Margin="2" VerticalAlignment="Center" > </TextBox> </StackPanel> </Border> </StackPanel> </DataTemplate> </Window.Resources> <Grid> <ListBox Name="listbox1" Margin="5" HorizontalContentAlignment="Stretch" ><!-- 最外層ListBox--> <ListBox.ItemTemplate > <DataTemplate > <StackPanel Orientation="Horizontal" > <Border Margin="5" Padding="3" BorderBrush="Green" BorderThickness="1" CornerRadius="2"> <StackPanel Orientation="Horizontal" > <CheckBox Content="選擇該題" Margin="3"></CheckBox> <TextBlock Text="{Binding qutestionName}" Margin="3"/> <ListBox Name="listbox2" ItemsSource="{Binding choseItems}" ItemsPanel="{StaticResource itemspanel}" ItemTemplate="{StaticResource itemstemplate}"/> <!-- 如果內嵌項不需要單個項選擇,可考慮把ListBox換成ItemsControl--> </StackPanel> </Border> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Window>
第三:小結一下:
1:內嵌項經常不需要分開點擊顯示,則可以直接把內嵌ListBox換成ItemsControl,效果為單擊選中所有項;
2:內嵌項用Canvas沒有成功,會造成外ListBox沒有水平滾動條,用StackPanel來布局比較合適
3:嵌套類型模板的使用需要配合設置選中塊觸發界面顏色的變化,否則會很不習慣或很難看,可以參考我的"小顆豆計票統計器"選中項狀態圖,隨意更改外觀.