本次笔记涉及:ListBox、TextBox、Button、绑定、ItemSource、ObservableCollection、ICollectionView。
实现目标:ListBox显示一组数据,数据是User对象的Name属性;同时把ListBox选中项的Name属性显示在nameTextBox,把Age属性显示在ageTextBox;最后4个按钮,能选择第一个、前一个、后一个、最后一个ListBox中的项目。
界面如下:

实现方法:
方法一:因为是静态数据,所以直接在XAML中列出,然后采用绑定的方式。
XAML前台代码
<Window x:Class="KarliCards.Gui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:KarliCards.Gui"
mc:Ignorable="d"
Title="MainWindow" Height="228" Width="283">
<Window.Resources>
<local:Users x:Key="UserSet">
<local:User Name="赵子龙" Age="120"/>
<local:User Name="谢浩然" Age="10"/>
<local:User Name="林黛玉" Age="20"/>
<local:User Name="花木兰" Age="90"/>
<local:User Name="诸葛亮" Age="120"/>
<local:User Name="穆桂英" Age="90"/>
<local:User Name="贾宝玉" Age="20"/>
<local:User Name="李宛桐" Age="10"/>
</local:Users>
</Window.Resources>
<Grid Name="grid" Height="195" DataContext="{StaticResource UserSet}">
<TextBlock Height="23" Width="43" Text="Name: " HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="6, 71, 0, 0"/>
<TextBlock Height="23" Width="43" Text="Age: " HorizontalAlignment="Left" VerticalAlignment="Bottom"
Margin="6, 0, 0, 72"/>
<TextBox Height="23" Width="120" Name="nameTextBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="129, 68, 0, 0"
Text="{Binding Path=Name}"/>
<!--Binding没有写ElementName对象,默认就是数据上下文DataContext-->
<TextBox Height="23" Width="120" Name="ageTextBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="129, 100, 0, 0"
Text="{Binding Path=Age}"/>
<TextBlock Height="23" Width="58" Name="textBlock3" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="6, 10, 0, 0" Text="DataSet: "/>
<ListBox Height="52" Width="179" Name="userListBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="70, 10, 0, 0"
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="Age"
DisplayMemberPath="Name" />
<Button Content="First" Height="23" Width="47" Name="firstButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6, 127, 0, 0"
Click="firstButton_Click"/>
<Button Content="Previous" Height="23" Width="47" Name="previousButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="70, 127, 0, 0"
Click="previousButton_Click"/>
<Button Content="Next" Height="23" Width="47" Name="nextButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="137, 127, 0, 0"
Click="nextButton_Click"/>
<Button Content="Last" Height="23" Width="47" Name="lastButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="202, 127, 0, 0"
Click="lastButton_Click"/>
</Grid>
</Window>
后台CS代码,使用了ObservableCollection集合。
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.ComponentModel;
using System.Collections.ObjectModel;
namespace KarliCards.Gui
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
ICollectionView GetUserSetView()
{
Users users = (Users)this.FindResource("UserSet");
return CollectionViewSource.GetDefaultView(users);
}
//User user = new User();
//List<User> list = new List<User>();
public MainWindow()
{
InitializeComponent();
}
private void firstButton_Click(object sender, RoutedEventArgs e)
{
if(userListBox.SelectedItem!=null)
{
userListBox.SelectedIndex = 0;
}
}
private void previousButton_Click(object sender, RoutedEventArgs e)
{
ICollectionView view = GetUserSetView();
view.MoveCurrentToPrevious();
if(view.IsCurrentBeforeFirst)
{
view.MoveCurrentToFirst();
}
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
ICollectionView view = GetUserSetView();
view.MoveCurrentToNext();
if (view.IsCurrentAfterLast)
{
view.MoveCurrentToLast();
}
}
private void lastButton_Click(object sender, RoutedEventArgs e)
{
if(userListBox.SelectedItem!=null)
{
userListBox.SelectedIndex = userListBox.Items.Count - 1;
}
}
}
// INotifyPropertyChanged是.net内置的接口
// 数据绑定会检测DataContext是否实现了INotifyPropertyChanged
// 如果实现了,就会监听PropertyChanged得知属性变化
public class User : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
}
}
int age;
public int Age
{
get { return this.age; }
set
{
this.age = value;
// 触发事件
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Age"));
}
}
public User() { }
public User(string name, int age)
{
this.name = name;
this.age = age;
}
}
public class Users : ObservableCollection<User>
{
}
}
方法二:在后台CS文件中赋初值,然后指定ItemSource。
前台XAML代码:
<Window x:Class="KarliCards.Gui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:KarliCards.Gui"
mc:Ignorable="d"
Title="MainWindow" Height="228" Width="283" Loaded="Window_Loaded">
<Grid Name="grid" Height="195" DataContext="list">
<TextBlock Height="23" Width="43" Text="Name: " HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="6, 71, 0, 0"/>
<TextBlock Height="23" Width="43" Text="Age: " HorizontalAlignment="Left" VerticalAlignment="Bottom"
Margin="6, 0, 0, 72"/>
<TextBox Height="23" Width="120" Name="nameTextBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="129, 68, 0, 0" />
<!--Binding没有写ElementName对象,默认就是数据上下文DataContext-->
<TextBox Height="23" Width="120" Name="ageTextBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="129, 100, 0, 0"/>
<TextBlock Height="23" Width="58" Name="textBlock3" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="6, 10, 0, 0" Text="DataSet: "/>
<ListBox Height="52" Width="179" Name="userListBox" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="70, 10, 0, 0"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="Age"
SelectionChanged="userListBox_SelectionChanged"
DisplayMemberPath="Name" />
<Button Content="First" Height="23" Width="47" Name="firstButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6, 127, 0, 0"
Click="firstButton_Click"/>
<Button Content="Previous" Height="23" Width="47" Name="previousButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="70, 127, 0, 0"
Click="previousButton_Click"/>
<Button Content="Next" Height="23" Width="47" Name="nextButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="137, 127, 0, 0"
Click="nextButton_Click"/>
<Button Content="Last" Height="23" Width="47" Name="lastButton"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="202, 127, 0, 0"
Click="lastButton_Click"/>
</Grid>
</Window>
后台CS代码:通过ListBox的SelectedIndex来做处理
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.ComponentModel;
using System.Collections.ObjectModel;
namespace KarliCards.Gui
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void firstButton_Click(object sender, RoutedEventArgs e)
{
if(userListBox.SelectedItem!=null)
{
userListBox.SelectedIndex = 0;
}
}
private void previousButton_Click(object sender, RoutedEventArgs e)
{
int index = userListBox.SelectedIndex;
if(index>0)
{
userListBox.SelectedIndex -= 1;
}
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
int index = userListBox.SelectedIndex;
if(index < userListBox.Items.Count-1)
{
userListBox.SelectedIndex += 1;
}
}
private void lastButton_Click(object sender, RoutedEventArgs e)
{
if(userListBox.SelectedItem!=null)
{
userListBox.SelectedIndex = userListBox.Items.Count - 1;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<User> list = new List<User>();
list.Add(new User() { Name = "赵子龙", Age = 120 });
list.Add(new User() { Name = "谢浩然", Age = 10 });
list.Add(new User() { Name = "林黛玉", Age = 20 });
list.Add(new User() { Name = "花木兰", Age = 90 });
list.Add(new User() { Name = "诸葛亮", Age = 120 });
list.Add(new User() { Name = "穆桂英", Age = 90 });
list.Add(new User("贾宝玉", 20));
list.Add(new User("李宛桐", 10));
this.userListBox.ItemsSource = list;
}
private void userListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// SelectedItem是Object对象,可以转换为任何对象,而本身它是User对象
User str = (User)userListBox.SelectedItem;
nameTextBox.Text = str.Name;
ageTextBox.Text = str.Age.ToString();
}
}
// INotifyPropertyChanged是.net内置的接口
// 数据绑定会检测DataContext是否实现了INotifyPropertyChanged
// 如果实现了,就会监听PropertyChanged得知属性变化
public class User : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
}
}
int age;
public int Age
{
get { return this.age; }
set
{
this.age = value;
// 触发事件
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Age"));
}
}
public User() { }
public User(string name, int age)
{
this.name = name;
this.age = age;
}
}
}
方法三:综合方法一和方法二,ListBox的ItemSource在后台获取,同时使用ObservableCollection集合、ICollectionView接口。ICollectionView接口有一些现成的方法,如MoveCurrentToFirst()、MoveCurrentToNext()等。没实验成功,待续。
这篇笔记介绍了WPF中数据绑定的概念,详细讲解了如何使用ListBox、TextBox和Button结合ObservableCollection进行数据展示。通过设置ItemSource,实现了在ListBox中显示User对象的Name属性,并将选中项的Name和Age属性同步到文本框。同时,文章还探讨了通过SelectedIndex处理按钮事件来选择ListBox项的方法,并提到了ICollectionView接口的可能性。
362

被折叠的 条评论
为什么被折叠?



