我正在尝试制作一个在 WPF 上进行分组的列表框。这可以很容易地完成,如 WPF4 Unleashed 和 Web 上的任何其他教程中所述。
XAML(这里有两个列表,有和没有分组 + 按钮来更新它们的公共项目源):
<Window x:Class="GroupTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" ItemsSource="{Binding Path=Items}" x:Name="_listBox1">
<ListBox.GroupStyle>
<x:Static Member="GroupStyle.Default" />
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Row="1" ItemsSource="{Binding Path=Items}" x:Name="_listBox2">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="2" Content="Update Items" Click="Button_Click" Focusable="False"/>
</Grid>
</Window>
代码(这里我在页面加载时设置分组并在单击按钮时更新/替换项目源):
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;
namespace GroupTest
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public class Item
{
public string Name { get; set; }
public bool Flag { get; set; }
}
private List<Item> _items;
public List<Item> Items
{
get { return _items; }
set
{
if (_items != value)
{
_items = value;
NotifyPropertyChanged("Items");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
MakeItems();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ICollectionView view = CollectionViewSource.GetDefaultView(_listBox1.Items);
view.GroupDescriptions.Add(new PropertyGroupDescription("Flag"));
}
private void MakeItems()
{
_items = new List<Item>();
_items.Add(new Item() { Name = "1", Flag = true });
_items.Add(new Item() { Name = "2", Flag = true });
_items.Add(new Item() { Name = "3", Flag = false });
_items.Add(new Item() { Name = "4", Flag = true });
_items.Add(new Item() { Name = "5", Flag = false });
}
private void UpdateItems()
{
Items = new List<Item>(_items);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
UpdateItems();
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
它可以工作,但是有一个我无法解决的奇怪错误。每次我更新其项目源时,带有分组的列表 #1 都会失去焦点。而没有分组的列表#2保持焦点。
这是完整项目源的链接:https ://dl.dropbox.com/u/60611528/GroupTest.zip
有什么建议么?提前致谢!
更新 我尝试将 Items 设为 ObservableCollection<>,但这并没有帮助。焦点仍然从分组列表中消失。
更新 2 我的真实应用程序在模型类中有项目,它不知道列表框。我希望有一个解决方案可以在不紧密耦合窗口和模型类的情况下解决问题。