思路:大项目的每项中包含一个小项目集合,用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:嵌套类型模板的使用需要配合设置选中块触发界面颜色的变化,否则会很不习惯或很难看,可以参考我的"小颗豆计票统计器"选中项状态图,随意更改外观.