当DataGrid使用对象进行了分组时候,该对象类型必须实现 IComparable 接口,否则出错:必须至少有一个对象实现。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ObservableCollection<TaskProject> list1 = new ObservableCollection<TaskProject>();
for (int i = 1; i <= 2; i++)
{
list1.Add(new TaskProject()
{
ProjectId = i,
ProjectName = "Project " + i.ToString(),
});
}
list1.Add(new TaskProject() { ProjectId = 1, ProjectName = "Project 1" });
this.dataGrid2.ItemsSource = new PagedCollectionView(list1);
ObservableCollection<Task> taskList = new ObservableCollection<Task>();
// Generate some task data and add it to the task list.
for (int i = 1; i <= 100; i++)
{
taskList.Add(new Task()
{
Area = i / 3D,
ProjectName = "公司 " + ((i % 5) + 1).ToString(),
TaskName = "Task " + i.ToString(),
Project = list1[i % list1.Count],
DueDate = DateTime.Now.AddDays(i),
Complete = (i % 2 == 0),
Notes = "Task " + i.ToString() + " is due on "
+ DateTime.Now.AddDays(i) + ". Lorum ipsum..."
});
}
PagedCollectionView taskListView = new PagedCollectionView(taskList);
taskListView.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(taskListView_CollectionChanged);
this.dataGrid1.ItemsSource = taskListView;
if (taskListView.CanGroup == true)
{
PropertyGroupDescription group = new PropertyGroupDescription("Project");
group.Converter = new ProjectConverter();
taskListView.GroupDescriptions.Add(group);
// Then group by Complete status.
taskListView.GroupDescriptions.Add(new PropertyGroupDescription("Complete"));
}
if (taskListView.CanSort == true)
{
// By default, sort by ProjectName.
taskListView.SortDescriptions.Add(new SortDescription("ProjectName", ListSortDirection.Ascending));
}
dataPager1.Source = taskListView;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Task : System.ComponentModel.INotifyPropertyChanged, IEditableObject
{
// The Task class implements INotifyPropertyChanged and IEditableObject
// so that the datagrid can properly respond to changes to the
// data collection and edits made in the DataGrid.
// Private task data.
private string m_ProjectName = string.Empty;
private string m_TaskName = string.Empty;
private DateTime m_DueDate = DateTime.Now;
private bool m_Complete = false;
private string m_Notes = string.Empty;
// Data for undoing canceled edits.
private Task temp_Task = null;
private bool m_Editing = false;
public double Area { get; set; }
// Public properties.
[Display(Name = "公司")]
public string ProjectName
{
get { return this.m_ProjectName; }
set
{
if (value != this.m_ProjectName)
{
this.m_ProjectName = value;
NotifyPropertyChanged("ProjectName");
}
}
}
[Display(Name = "项目")]
public TaskProject Project
{
get;
set;
}
[Display(Name = "Task")]
public string TaskName
{
get { return this.m_TaskName; }
set
{
if (value != this.m_TaskName)
{
this.m_TaskName = value;
NotifyPropertyChanged("TaskName");
}
}
}
[Display(Name = "Due Date")]
public DateTime DueDate
{
get { return this.m_DueDate; }
set
{
if (value != this.m_DueDate)
{
this.m_DueDate = value;
NotifyPropertyChanged("DueDate");
}
}
}
public bool Complete
{
get { return this.m_Complete; }
set
{
if (value != this.m_Complete)
{
this.m_Complete = value;
NotifyPropertyChanged("Complete");
}
}
}
public string Notes
{
get { return this.m_Notes; }
set
{
if (value != this.m_Notes)
{
this.m_Notes = value;
NotifyPropertyChanged("Notes");
}
}
}
// Implement INotifyPropertyChanged interface.
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// Implement IEditableObject interface.
public void BeginEdit()
{
if (m_Editing == false)
{
temp_Task = this.MemberwiseClone() as Task;
m_Editing = true;
}
}
public void CancelEdit()
{
if (m_Editing == true)
{
this.ProjectName = temp_Task.ProjectName;
this.TaskName = temp_Task.TaskName;
this.DueDate = temp_Task.DueDate;
this.Complete = temp_Task.Complete;
this.Notes = temp_Task.Notes;
m_Editing = false;
}
}
public void EndEdit()
{
if (m_Editing == true)
{
temp_Task = null;
m_Editing = false;
}
}
}
{
// The Task class implements INotifyPropertyChanged and IEditableObject
// so that the datagrid can properly respond to changes to the
// data collection and edits made in the DataGrid.
// Private task data.
private string m_ProjectName = string.Empty;
private string m_TaskName = string.Empty;
private DateTime m_DueDate = DateTime.Now;
private bool m_Complete = false;
private string m_Notes = string.Empty;
// Data for undoing canceled edits.
private Task temp_Task = null;
private bool m_Editing = false;
public double Area { get; set; }
// Public properties.
[Display(Name = "公司")]
public string ProjectName
{
get { return this.m_ProjectName; }
set
{
if (value != this.m_ProjectName)
{
this.m_ProjectName = value;
NotifyPropertyChanged("ProjectName");
}
}
}
[Display(Name = "项目")]
public TaskProject Project
{
get;
set;
}
[Display(Name = "Task")]
public string TaskName
{
get { return this.m_TaskName; }
set
{
if (value != this.m_TaskName)
{
this.m_TaskName = value;
NotifyPropertyChanged("TaskName");
}
}
}
[Display(Name = "Due Date")]
public DateTime DueDate
{
get { return this.m_DueDate; }
set
{
if (value != this.m_DueDate)
{
this.m_DueDate = value;
NotifyPropertyChanged("DueDate");
}
}
}
public bool Complete
{
get { return this.m_Complete; }
set
{
if (value != this.m_Complete)
{
this.m_Complete = value;
NotifyPropertyChanged("Complete");
}
}
}
public string Notes
{
get { return this.m_Notes; }
set
{
if (value != this.m_Notes)
{
this.m_Notes = value;
NotifyPropertyChanged("Notes");
}
}
}
// Implement INotifyPropertyChanged interface.
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// Implement IEditableObject interface.
public void BeginEdit()
{
if (m_Editing == false)
{
temp_Task = this.MemberwiseClone() as Task;
m_Editing = true;
}
}
public void CancelEdit()
{
if (m_Editing == true)
{
this.ProjectName = temp_Task.ProjectName;
this.TaskName = temp_Task.TaskName;
this.DueDate = temp_Task.DueDate;
this.Complete = temp_Task.Complete;
this.Notes = temp_Task.Notes;
m_Editing = false;
}
}
public void EndEdit()
{
if (m_Editing == true)
{
temp_Task = null;
m_Editing = false;
}
}
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ProjectConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value as TaskProject).ProjectName;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return 0;
}
}
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value as TaskProject).ProjectName;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return 0;
}
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class TaskProject : IComparable, IComparable<TaskProject>
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public override string ToString()
{
return this.ProjectName;
}
#region IComparable 成员
public int CompareTo(object obj)
{
return this.CompareTo(obj as TaskProject);
}
#endregion
#region IComparable<TaskProject> 成员
public int CompareTo(TaskProject other)
{
if (other == null)
{
return -1;
}
return this.ProjectId - other.ProjectId;
}
#endregion
}
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public override string ToString()
{
return this.ProjectName;
}
#region IComparable 成员
public int CompareTo(object obj)
{
return this.CompareTo(obj as TaskProject);
}
#endregion
#region IComparable<TaskProject> 成员
public int CompareTo(TaskProject other)
{
if (other == null)
{
return -1;
}
return this.ProjectId - other.ProjectId;
}
#endregion
}