我有一個ObservableCollection<T>
。我已經將它綁定到一個ListBox控件,並且我已經添加了SortDescriptions
到ListBox上的Items集合,以使列表按我想要的方式排序。可觀察收藏物業集合中物品已更改
我想要使用的列表,任何任何屬性在子元素上更改時的點。
我所有的子元素都實現了INotifyPropertyChanged
。
我有一個ObservableCollection<T>
。我已經將它綁定到一個ListBox控件,並且我已經添加了SortDescriptions
到ListBox上的Items集合,以使列表按我想要的方式排序。可觀察收藏物業集合中物品已更改
我想要使用的列表,任何任何屬性在子元素上更改時的點。
我所有的子元素都實現了INotifyPropertyChanged
。
蠻力:
編輯:
代碼爲1,2就住在你的代碼隱藏。
#1,你會做這樣的事情:
private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach(SomeItem item in e.NewItems)
{
item.PropertyChanged += new PropertyChangedEventHandler(_SomeItem_PropertyChanged);
}
break;
....
**HANDLE OTHER CASES HERE**
....
}
}
#2,在您的CollectionChanged處理程序,你會做這樣的事情:
private void _SomeItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(theListBox.ItemsSource));
lcv.Refresh();
}
EDIT2: 然而,這種情況下,我會強烈建議您還檢查ListCollectionView.NeedsRefresh並只刷新如果設置。沒有理由重新排序,如果你的屬性已經改變,不影響排序。
這段代碼是否在我的表示層中? Window.Xaml.Cs? #1和#2的代碼是什麼樣的? – Nate 2009-06-18 21:25:47
This works。只要收集發生變化,它就會重新對收集進行分類。可以以更有效的方式進行操作,但這是它的要點。
public partial class TestWindow : Window {
ObservableCollection<TestClass> oc;
public TestWindow() {
InitializeComponent();
// Fill in the OC for testing
oc = new ObservableCollection<TestClass>();
foreach(char c in "abcdefghieeddjko") {
oc.Add(new TestClass(c.ToString(), c.ToString(), c.GetHashCode()));
}
lstbox.ItemsSource = oc;
// Set up the sorting (this is how you did it.. doesn't work)
lstbox.Items.SortDescriptions.Add(new SortDescription("A", ListSortDirection.Ascending));
// This is how we're going to do it
oc.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(oc_Sort);
}
void oc_Sort(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
// This sorts the oc and returns IEnumerable
var items = oc.OrderBy<TestClass, int>((x) => (x.C));
// Rest converst IEnumerable back to OC and assigns it
ObservableCollection<TestClass> temp = new ObservableCollection<TestClass>();
foreach(var item in items) {
temp.Add(item);
}
oc = temp;
}
private void Button_Click(object sender, RoutedEventArgs e) {
string a = "grrrr";
string b = "ddddd";
int c = 383857;
oc.Add(new TestClass(a, b, c));
}
}
public class TestClass : INotifyPropertyChanged {
private string a;
private string b;
private int c;
public TestClass(string f, string g, int i) {
a = f;
b = g;
c = i;
}
public string A {
get { return a; }
set { a = value; OnPropertyChanged("A"); }
}
public string B {
get { return b; }
set { b = value; OnPropertyChanged("B"); }
}
public int C {
get { return c; }
set { c = value; OnPropertyChanged("C"); }
}
#region onpropertychanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) {
if(this.PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
XAML:
<Window x:Class="ServiceManager.TestWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="TestWindow" Height="500" Width="500"> <DockPanel> <ListBox ItemsSource="{Binding}" x:Name="lstbox"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Label Content="{Binding Path=A}"/> <Label Content="{Binding Path=B}"/> <Label Content="{Binding Path=C}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button Click="Button_Click" Content="Click" /> </DockPanel> </Window>
所以,你在你的OC綁定到一個列表框和對列表框中sortdescription? – apandit 2009-06-18 21:19:12
這是正確的。當兒童項目的財產發生變化時,我希望能夠反映這種變化。 – Nate 2009-06-18 21:22:23