ObservableCollection<T>是.NET中的一个集合类,位于System.Collections.ObjectModel命名空间下。它是专门为WPF数据绑定设计的,当集合中的项被添加、移除或整个列表被刷新时,会自动通知UI进行更新。
ListBox是WPF中的一个列表控件,用于显示可滚动的项目列表,用户可以选择一个或多个项目。
using System.Collections.ObjectModel;
using System.ComponentModel;
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged(nameof(Items));
}
}
public MainViewModel()
{
Items = new ObservableCollection<string>
{
"Item 1",
"Item 2",
"Item 3"
};
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ObservableCollection Demo" Height="350" Width="525">
<Grid>
<ListBox ItemsSource="{Binding Items}"
DisplayMemberPath="."
Margin="10"/>
</Grid>
</Window>
在Window的代码后台文件中:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
原因:可能是在非UI线程上修改了集合
解决方案:
Application.Current.Dispatcher.Invoke(() =>
{
Items.Add("New Item");
});
解决方案:添加SelectedItem绑定
<ListBox ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
DisplayMemberPath="."/>
然后在ViewModel中添加:
private string _selectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
}
}
解决方案:设置ItemTemplate或重写ToString()
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}" Margin="10,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
using System.ComponentModel;
public class SortedObservableCollection<T> : ObservableCollection<T>
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
if (e.Action == NotifyCollectionChangedAction.Add)
{
var query = this.Select((item, index) => (Item: item, Index: index))
.OrderBy(t => t.Item, Comparer<T>.Default);
var map = query.Select((t, i) => (OldIndex: t.Index, NewIndex: i))
.Where(o => o.OldIndex != o.NewIndex);
foreach (var pair in map)
{
Move(pair.OldIndex, pair.NewIndex);
}
}
}
}
public ICollectionView FilteredItems => CollectionViewSource.GetDefaultView(Items);
// 设置过滤条件
FilteredItems.Filter = item => ((string)item).Contains("filter");
通过以上方法和示例,您可以有效地将ObservableCollection绑定到WPF ListBox,并处理各种常见场景和问题。
没有搜到相关的文章