WPF教程ListBox使用CheckBox和绑定数据
C#和WPF中的ListBox是ListBoxItems的集合。本教程中的代码示例演示了如何添加列表框项、将项添加到ListBox、从ListBox中删除项以及将ListBox绑定到数据源。
<ListBox></ListBox>
Width和Height属性表示ListBox的宽度和高度。Name属性表示控件的名称,它是控件的唯一标识符。Margin属性告诉ListBox在父控件上的位置。HorizontalAlignment和VerticalAlignment属性用于设置水平和垂直对齐方式。
以下代码片段设置ListBox控件的名称、高度和宽度。该代码还将水平对齐设置为左对齐,垂直对齐设置为顶部。
<ListBox Margin="10,10,0,13" Name="listBox1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="194" Height="200" />
将项目添加到ListBox控件
ListBox控件是ListBoxItems的集合。下面的代码示例将项目集合添加到ListBox控件。
<ListBox Margin="10,10,0,13" Name="listBox1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="194" Height="200">
<ListBoxItem Content="Coffie"></ListBoxItem>
<ListBoxItem Content="Tea"></ListBoxItem>
<ListBoxItem Content="Orange Juice"></ListBoxItem>
<ListBoxItem Content="Milk"></ListBoxItem>
<ListBoxItem Content="Iced Tea"></ListBoxItem>
<ListBoxItem Content="Mango Shake"></ListBoxItem>
</ListBox>
动态添加ListBox项,我们看到了如何在设计时从XAML将项目添加到ListBox。我们可以从代码中将项目添加到ListBox。
让我们更改我们的UI并向页面添加一个TextBox和一个按钮控件。TextBox和Button控件的XAML代码如下所示。
<TextBox Height="23" HorizontalAlignment="Left" Margin="8,14,0,0" Name="textBox1" VerticalAlignment="Top" Width="127" />
<Button Height="23" Margin="140,14,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="76" Click="button1_Click"> Add Item </Button>
最终的 UI 类似于图。
在按钮单击事件处理程序中,我们通过调用 ListBox.Items.Add 方法将 TextBox 的内容添加到 ListBox。以下代码将TextBox内容添加到ListBox项。
private void button1_Click(object sender, RoutedEventArgs e) {
listBox1.Items.Add(textBox1.Text);
在按钮单击事件处理程序中,我们通过调用ListBox.Items.Add方法将TextBox的内容添加到ListBox。
现在,如果您在TextBox中输入文本并单击AddItem按钮,它会将TextBox的内容添加到ListBox。
删除列表框项目
我们可以使用ListBox.Items.Remove或ListBox.Items.RemoveAt方法从ListBox中的项目集合中删除一个项目。RemoveAt方法获取集合中项目的索引。
现在,我们修改我们的应用程序并添加一个名为DeleteItem的新按钮。此按钮的XAML代码如下所示。
<Button Height="23" Margin="226,14,124,0" Name="DeleteButton" VerticalAlignment="Top" Click="DeleteButton_Click"> Delete Item</Button>
按钮单击事件处理程序如下所示。单击此按钮,我们找到所选项目的索引并调用 ListBox.Items.RemoveAt 方法,如下所示。
private void DeleteButton_Click(object sender, RoutedEventArgs e) {
listBox1.Items.RemoveAt(listBox1.Items.IndexOf(listBox1.SelectedItem));
Formatting ListBox Items
ListBoxItem的Foreground和Background属性表示项目的背景色和前景色。以下代码片段设置ListBoxItem的背景和前景色。
<ListBoxItem Background="LightCoral" Foreground="Red" Content="Coffie"></ListBoxItem>
FontFamily、FontSize和FontWeight用于设置ListBoxItem的字体。以下代码片段设置ListBoxItem的字体verdana、大小12和粗体。
<ListBoxItem Background="LightCoral" Foreground="Red" Content="Coffie" FontFamily="Verdana" FontSize="12" FontWeight="Bold"></ListBoxItem>
我设置了ListBoxItems的以下属性。
<ListBoxItem Background="LightCoral" Foreground="Red" Content="Coffie" FontFamily="Verdana" FontSize="12" FontWeight="Bold"></ListBoxItem>
<ListBoxItem Background="LightGray" Foreground="Black" Content="Tea" FontFamily="Georgia" FontSize="14" FontWeight="Bold"></ListBoxItem>
<ListBoxItem Background="LightBlue" Foreground="Purple" Content="Orange Juice" FontFamily="Verdana" FontSize="12" FontWeight="Bold"></ListBoxItem>
<ListBoxItem Background="LightGreen" Foreground="Green" Content="Milk" FontFamily="Georgia" FontSize="14" FontWeight="Bold"></ListBoxItem>
<ListBoxItem Background="LightBlue" Foreground="Blue" Content="Iced Tea" FontFamily="Verdana" FontSize="12" FontWeight="Bold"></ListBoxItem>
<ListBoxItem Background="LightSlateGray" Foreground="Orange" Content="Mango Shake" FontFamily="Georgia" FontSize="14" FontWeight="Bold"></ListBoxItem>
在WPF列表框中加载图片
我们可以在ListBoxItem中放置任何控件,例如图片和文本。为了与一些文本并排显示图片 ,我只需在StackPanel中放置一个Image和TextBlock控件。Image.Source属性采用您希望在Image控件中显示的图片的名称,TextBlock.Text属性采用您希望在TextBlock中显示的字符串。
以下代码片段将图片和文本添加到ListBoxItem。
<ListBoxItem Background="LightCoral" Foreground="Red" FontFamily="Verdana" FontSize="12" FontWeight="Bold">
<StackPanel Orientation="Horizontal">
<Image Source="coffie.jpg" Height="30"></Image>
<TextBlock Text="Coffie"></TextBlock>
</StackPanel>
</ListBoxItem>
带有复选框的列表框
如果将CheckBox控件放在ListBoxItems中,则会生成一个带有复选框的ListBox控件。CheckBox也可以在其中托管控件。例如,我们可以将图像和文本块作为CheckBox的内容。
以下代码片段将带有图像和文本的CheckBox添加到ListBoxItem。
<ListBoxItem Background="LightCoral" Foreground="Red" FontFamily="Verdana" FontSize="12" FontWeight="Bold">
<CheckBox Name="CoffieCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="coffie.jpg" Height="30"></Image>
<TextBlock Text="Coffie"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
我更改了ListBoxItems的代码并将以下CheckBox添加到项目中。如您所见,我使用Name属性设置了CheckBox的名称。如果您需要访问这些CheckBox,您可以使用它们的Name属性在代码中访问它们。
<ListBoxItem Background="LightCoral" Foreground="Red" FontFamily="Verdana" FontSize="12" FontWeight="Bold">
<CheckBox Name="CoffieCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="coffie.jpg" Height="30"></Image>
<TextBlock Text="Coffie"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
<ListBoxItem Background="LightGray" Foreground="Black" FontFamily="Georgia" FontSize="14" FontWeight="Bold">
<CheckBox Name="TeaCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="tea.jpg" Height="30"></Image>
<TextBlock Text="Tea"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
<ListBoxItem Background="LightBlue" Foreground="Purple" FontFamily="Verdana" FontSize="12" FontWeight="Bold">
<CheckBox Name="OrangeJuiceCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="OrangeJuice.jpg" Height="40"></Image>
<TextBlock Text="OrangeJuice"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
<ListBoxItem Background="LightGreen" Foreground="Green" FontFamily="Georgia" FontSize="14" FontWeight="Bold">
<CheckBox Name="MilkCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="Milk.jpg" Height="30"></Image>
<TextBlock Text="Milk"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
<ListBoxItem Background="LightBlue" Foreground="Blue" FontFamily="Verdana" FontSize="12" FontWeight="Bold">
<CheckBox Name="IcedTeaCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="IcedTea.jpg" Height="30"></Image>
<TextBlock Text="Iced Tea"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
<ListBoxItem Background="LightSlateGray" Foreground="Orange" FontFamily="Georgia" FontSize="14" FontWeight="Bold">
<CheckBox Name="MangoShakeCheckBox">
<StackPanel Orientation="Horizontal">
<Image Source="MangoShake.jpg" Height="30"></Image>
<TextBlock Text="Mango Shake"></TextBlock>
</StackPanel>
</CheckBox>
</ListBoxItem>
ListBox控件中的数据绑定
.NET3.0和3.5中将数据绑定搞得一团糟。他们没有让事情变得更简单,而是让事情变得复杂。也许他们在未来有一些更大的计划,但到目前为止,我已经看到使用依赖对象和属性、LINQ和LINQ、 WCF和ASP.NET Web服务进行绑定,这一切看起来都是一团糟。它甚至不接近我们在 .NET1.0和2.0中的ADO.NET模型。我希望他们能在不久的将来收拾这个烂摊子。
ListBox的ItemsSource属性用于将IEnumerable的集合(例如ArrayList)绑定到ListBox控件。
LeftListBox.ItemsSource = LoadListBoxData();
private ArrayList LoadListBoxData() {
ArrayList itemsList = new ArrayList();
itemsList.Add("Coffie");
itemsList.Add("Tea");
itemsList.Add("Orange Juice");
itemsList.Add("Milk");
itemsList.Add("Mango Shake");
itemsList.Add("Iced Tea");
itemsList.Add("Soda");
itemsList.Add("Water");
return itemsList;
将数据从一个ListBox传输到另一个
我们已经看到了很多要求,其中一个页面有两个ListBox控件,而左边的ListBox显示一个项目列表。使用按钮我们可以从左侧ListBox添加项目并将它们添加到右侧ListBox,使用删除按钮我们可以从右侧ListBox删除项目并将它们添加回左侧ListBox。
此示例显示了我们如何将项目从一个ListBox移动到另一个。最终页面如图7所示。Add按钮将所选项目添加到右侧ListBox并从左侧ListBox中删除。Remove按钮从右侧ListBox中删除所选项目并添加回左侧ListBox。
<ListBox Margin="11,13,355,11" Name="LeftListBox" />
<ListBox Margin="0,13,21,11" Name="RightListBox" HorizontalAlignment="Right" Width="216" />
<Button Name="AddButton" Height="23" Margin="248,78,261,0" VerticalAlignment="Top" Click="AddButton_Click">Add >></Button>
<Button Name="RemoveButton" Margin="248,121,261,117" Click="RemoveButton_Click"><< Remove</Button>
在Window加载事件中,我们通过将ItemsSource属性设置为ArrayList来创建数据项并将其加载到ListBox。
private void Window_Loaded(object sender, RoutedEventArgs e) {
myDataList = LoadListBoxData();
// Bind ArrayList with the ListBox
LeftListBox.ItemsSource = myDataList;
private ArrayList LoadListBoxData() {
ArrayList itemsList = new ArrayList();
itemsList.Add("Coffie");
itemsList.Add("Tea");
itemsList.Add("Orange Juice");
itemsList.Add("Milk");
itemsList.Add("Mango Shake");
itemsList.Add("Iced Tea");
itemsList.Add("Soda");
itemsList.Add("Water");
return itemsList;
在添加按钮单击事件处理程序中,我们在左侧ListBox中获取所选项目的值和索引,并将其添加到右侧ListBox并从作为我们的数据源的ArrayList中删除该项目。ApplyBinding方法只是删除ListBox的当前绑定并与更新的ArrayList重新绑定。
private void AddButton_Click(object sender, RoutedEventArgs e) {
// Find the right item and it's value and index
currentItemText = LeftListBox.SelectedValue.ToString();
currentItemIndex = LeftListBox.SelectedIndex;
RightListBox.Items.Add(currentItemText);
if (myDataList != null) {
myDataList.RemoveAt(currentItemIndex);
// Refresh data binding
ApplyDataBinding();
///<summary>
/// Refreshes data binding
///</summary>
private void ApplyDataBinding() {
LeftListBox.ItemsSource = null;
// Bind ArrayList with the ListBox
LeftListBox.ItemsSource = myDataList;
同样,在“删除”按钮单击事件处理程序上,我们从右侧ListBox获取所选项目文本和索引,并将其添加到ArrayList并从右侧ListBox中删除。
private void RemoveButton_Click(object sender, RoutedEventArgs e)
// Find the right item and it's value and index
currentItemText = RightListBox.SelectedValue.ToString();
currentItemIndex = RightListBox.SelectedIndex;
// Add RightListBox item to the ArrayList
myDataList.Add(currentItemText);
RightListBox.Items.RemoveAt(RightListBox.Items.IndexOf(RightListBox.SelectedItem));
// Refresh data binding
ApplyDataBinding();
与数据库的数据绑定
我们使用SQLServer自带的Northwind.mdf数据库。在我们的应用程序中,我们将从客户表中读取数据。客户表列如图所示。
我们将读取WPF ListBox控件中的ContactName、Address、City和Country列。最终的ListBox类似于下图。
现在让我们看看我们的XAML文件。我们创建名为listBoxTemplate的资源DataTemplate类型。数据模板用于以格式化的方式表示数据。数据模板有两个停靠面板,其中第一个面板显示名称,第二个面板使用TextBlock控件显示地址、城市和国家/地区列。
<Window.Resources>
<DataTemplate x:Key="listBoxTemplate">
<StackPanel Margin="3">
<DockPanel>
<TextBlock FontWeight="Bold" Text="Name:" DockPanel.Dock="Left" Margin="5,0,10,0" />
<TextBlock Text="" />
<TextBlock Text="{Binding ContactName}" Foreground="Green" FontWeight="Bold" />
</DockPanel>
<DockPanel>
<TextBlock FontWeight="Bold" Text="Address:" Foreground="DarkOrange" DockPanel.Dock="Left" Margin="5,0,5,0" />
<TextBlock Text="{Binding Address}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding City}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding Country}" />
</DockPanel>
</StackPanel>
</DataTemplate>
</Window.Resources>
现在我们添加一个ListBox控件并将其ItemsSource属性设置为DataSet的第一个DataTable并将ItemTemplate设置为上面定义的资源。
<ListBox Margin="17,8,15,26" Name="listBox1" ItemsSource="{Binding Tables[0]}" ItemTemplate="{StaticResource listBoxTemplate}" />
现在在我们后面的代码中,我们定义了以下变量。
public SqlConnection connection;
public SqlCommand command;
string sql = "SELECT ContactName, Address, City, Country FROM Customers";
string connectionString = @ "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True";
现在在 Windows_Loaded 方法中,我们调用 BindData 方法,在 BindData 方法中,我们创建一个连接、数据适配器,并使用 SqlDataAdapter.Fill() 方法填充 DataSet。
private void Window_Loaded(object sender, RoutedEventArgs e) {
BindData();
private void BindData() {
DataSet dtSet = new DataSet();
using(connection = new SqlConnection(connectionString)) {
command = new SqlCommand(sql, connection);
SqlDataAdapter adapter = new SqlDataAdapter();
connection.Open();
adapter.SelectCommand = command;
adapter.Fill(dtSet, "Customers");
listBox1.DataContext = dtSet;
与 XML 的数据绑定
现在让我们看看如何将XML数据绑定到ListBox控件。XmlDataProvider用于在WPF中绑定XML数据。
这是在XAML中定义的包含书籍数据的XmlDataProvider。XML数据在x:Data标记中定义。
<XmlDataProvider x:Key="BooksData" XPath="Inventory/Books">
<x:XData>
<Inventory xmlns="">
<Books>
<Book Category="Programming">
<Title>A Programmer's Guide to ADO.NET</Title>
<Summary>Learn how to write database applications using ADO.NET and C#. </Summary>
<Author>Mahesh Chand</Author>
<Publisher>APress</Publisher>
</Book>
<Book Category="Programming">
<Title>Graphics Programming with GDI+</Title>
<Summary>Learn how to write graphics applications using GDI+ and C#. </Summary>
<Author>Mahesh Chand</Author>
<Publisher>Addison Wesley</Publisher>
</Book>
<Book Category="Programming">
<Title>Visual C#</Title>
<Summary>Learn how to write C# applications. </Summary>
<Author>Mike Gold</Author>
<Publisher>APress</Publisher>
</Book>
<Book Category="Programming">
<Title>Introducing Microsoft .NET</Title>
<Summary>Programming .NET </Summary>
<Author>Mathew Cochran</Author>
<Publisher>APress</Publisher>
</Book>
<Book Category="Database">
<Title>DBA Express</Title>
<Summary>DBA's Handbook </Summary>
<Author>Mahesh Chand</Author>
<Publisher>Microsoft</Publisher>
</Book>
</Books>
</Inventory>
</x:XData>
</XmlDataProvider>
要绑定XmlDataProvider,我们将ListBox的ItemsSource内的Source属性设置为XmlDataProvider的x:Key,XPath用于过滤数据。在ListBox.ItemTempate中,我们使用Binding属性。
ListBox Width="400" Height="300" Background="LightGray">
<ListBox.ItemsSource>
<Binding Source="{StaticResource BooksData}" XPath="*[@Category='Programming'] " />
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Title: " FontWeight="Bold" />
<TextBlock Foreground="Green">
<TextBlock.Text>
<Binding XPath="Title" />
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
与控件的数据绑定
我们将看到的最后一个数据绑定类型是如何使用WPF中的数据绑定在ListBox和其他控件之间提供数据交换。
我们将创建一个应用程序。我有一个带有颜色列表的ListBox、一个TextBox和一个Canvas。当我们从ListBox中选择一种颜色时,TextBox的文本和Canvas的颜色会动态地更改为在ListBox中选择的颜色,这可以在XAML中完成,而无需在代码隐藏文件中编写一行代码。
<StackPanel Orientation="Vertical">
<TextBlock Margin="10,10,10,10" FontWeight="Bold"> Pick a color from below list </TextBlock>
<ListBox Name="mcListBox" Height="100" Width="100" Margin="10,10,0,0" HorizontalAlignment="Left">
<ListBoxItem>Orange</ListBoxItem>
<ListBoxItem>Green</ListBoxItem>
<ListBoxItem>Blue</ListBoxItem>
<ListBoxItem>Gray</ListBoxItem>
<ListBoxItem>LightGray</ListBoxItem>
<ListBoxItem>Red</ListBoxItem>
</ListBox>
<TextBox Height="23" Name="textBox1" Width="120" Margin="10,10,0,0" HorizontalAlignment="Left">
<TextBox.Text>
<Binding ElementName="mcListBox" Path="SelectedItem.Content" />
</TextBox.Text>
</TextBox>