Nasıl yapılır: DataGrid denetiminde verileri gruplandırma, sıralama ve filtreleme
Verileri DataGrid gruplandırarak, sıralayarak ve filtreleyerek verileri farklı yollarla görüntülemek genellikle yararlı olur. İçindeki verileri gruplamak, sıralamak ve filtrelemek için DataGrid , CollectionView Bu işlevleri destekleyen bir öğesine bağlarsınız. Daha sonra, CollectionView temel alınan kaynak verileri etkilemeden içindeki verilerle çalışabilirsiniz. Koleksiyon görünümündeki değişiklikler DataGrid Kullanıcı arabiriminde (UI) yansıtılır.
CollectionViewSınıfı, arabirimini uygulayan bir veri kaynağı için gruplandırma ve sıralama işlevi sağlar IEnumerable . CollectionViewSourceSınıfı, XAML 'nin özelliklerini xaml 'den ayarlamanıza olanak sağlar CollectionView .
Bu örnekte, Task bir nesne koleksiyonu bir öğesine bağlanır CollectionViewSource . , CollectionViewSource İçin olarak kullanılır ItemsSourceDataGrid . Gruplandırma, sıralama ve filtreleme, üzerinde gerçekleştirilir CollectionViewSource ve DataGrid Kullanıcı arabiriminde görüntülenir.
DataGrid 'de gruplanmış veriler
CollectionViewSource 'u ItemSource olarak kullanma
Bir denetimdeki verileri gruplamak, sıralamak ve filtrelemek için DataGrid , ' yi DataGridCollectionView Bu işlevleri destekleyen bir öğesine bağlarsınız. Bu örnekte, bir DataGridCollectionViewSource nesne için bu işlevleri sağlayan bir öğesine bağlanır List<T>Task .
Bir DataGrid 'i CollectionViewSource 'a bağlamak için
Arabirimini uygulayan bir veri koleksiyonu oluşturun IEnumerable .
List<T>Koleksiyonunuzu oluşturmak için kullanırsanız, bir örneğinin örneğini oluşturmak yerine öğesinden devralan yeni bir sınıf oluşturmanız gerekir List<T>List<T> . Bu, XAML 'de koleksiyona veri bağlamanıza olanak sağlar.
Not
Koleksiyondaki nesneler INotifyPropertyChangedIEditableObject , DataGrid özelliğinin özellik değişikliklerine ve düzenlemelerine doğru yanıt vermesi için değiştirilen arabirimi ve arabirimi uygulamalıdır. Daha fazla bilgi için bkz. özellik değişiklik bildirimini uygulama.
// Requires using System.Collections.ObjectModel; public class Tasks : ObservableCollection<Task> { // Creating the Tasks collection in this way enables data binding from XAML. }' Requires Imports System.Collections.ObjectModel Public Class Tasks Inherits ObservableCollection(Of Task) ' Creating the Tasks collection in this way enables data binding from XAML. End ClassXAML 'de, koleksiyon sınıfının bir örneğini oluşturun ve X:Key yönergesiniayarlayın.
XAML 'de, sınıfının bir örneğini oluşturun CollectionViewSource , CollectionViewSourceayarlayın ve koleksiyon sınıfınızın örneğini olarak ayarlayın Source .
<Window.Resources> <local:Tasks x:Key="tasks" /> <CollectionViewSource x:Key="cvsTasks" Source="{StaticResource tasks}" Filter="CollectionViewSource_Filter"> </CollectionViewSource> </Window.Resources>Sınıfının bir örneğini oluşturun DataGrid ve ItemsSource özelliğini olarak ayarlayın CollectionViewSource .
<DataGrid x:Name="dataGrid1" ItemsSource="{Binding Source={StaticResource cvsTasks}}" CanUserAddRows="False">Kodunuzda öğesine erişmek için, CollectionViewSourceGetDefaultView yöntemini kullanarak öğesine bir başvuru alın CollectionViewSource .
ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource)
DataGrid içinde öğeleri gruplandırma
Öğelerin bir içinde nasıl gruplandığını belirtmek için, DataGridPropertyGroupDescription türü kaynak görünümündeki öğeleri gruplandırmak üzere kullanın.
XAML kullanarak bir DataGrid içindeki öğeleri gruplandırmak için
PropertyGroupDescriptionGruplandırma ölçütü olan özelliği belirleyen bir oluştur. Özelliği XAML 'de veya kodda belirtebilirsiniz.
XAML 'de, öğesini PropertyName Gruplandırma ölçütü olan özelliğin adına ayarlayın.
Kod ' da, özelliğin adını oluşturucuya göre grupla geçirin.
Öğesini PropertyGroupDescriptionCollectionViewSource.GroupDescriptions koleksiyona ekleyin.
PropertyGroupDescriptionGroupDescriptions Daha fazla gruplandırma düzeyi eklemek için koleksiyona ek örnekler ekleyin.
<CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="ProjectName"/> <PropertyGroupDescription PropertyName="Complete"/> </CollectionViewSource.GroupDescriptions>ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource); if (cvTasks != null && cvTasks.CanGroup == true) { cvTasks.GroupDescriptions.Clear(); cvTasks.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName")); cvTasks.GroupDescriptions.Add(new PropertyGroupDescription("Complete")); }Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource) If cvTasks IsNot Nothing And cvTasks.CanGroup = True Then cvTasks.GroupDescriptions.Clear() cvTasks.GroupDescriptions.Add(New PropertyGroupDescription("ProjectName")) cvTasks.GroupDescriptions.Add(New PropertyGroupDescription("Complete")) End IfBir grubu kaldırmak için koleksiyondan ' ı kaldırın PropertyGroupDescriptionGroupDescriptions .
Tüm grupları kaldırmak için Clear koleksiyonun yöntemini çağırın GroupDescriptions .
ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource); if (cvTasks != null) { cvTasks.GroupDescriptions.Clear(); }Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource) If cvTasks IsNot Nothing Then cvTasks.GroupDescriptions.Clear() End If
Öğeleri içinde gruplandırılırken DataGrid , GroupStyle her grubun görünümünü belirten bir tanımlayabilirsiniz. Öğesini GroupStyleGroupStyle DataGrid 'in koleksiyonuna ekleyerek uygularsınız. Birden çok gruplandırma düzeyine sahipseniz, her grup düzeyine farklı stiller uygulayabilirsiniz. Stiller tanımlandıkları sırayla uygulanır. Örneğin, iki stil tanımlarsanız, ilki en üst düzey satır gruplarına uygulanır. İkinci stil, ikinci düzeyde ve daha düşük tüm satır gruplarına uygulanır. , DataContextGroupStyleCollectionViewGroup Grubun temsil ettiği ' dır.
Satır grubu üstbilgilerinin görünümünü değiştirmek için
GroupStyleSatır grubunun görünümünü tanımlayan bir oluştur.
GroupStyleEtiketlerin içine yerleştirin
<DataGrid.GroupStyle>.<DataGrid.GroupStyle> <!-- Style for groups at top level. --> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Margin" Value="0,0,0,5"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True" Background="#FF112255" BorderBrush="#FF002255" Foreground="#FFEEEEEE" BorderThickness="1,1,1,5"> <Expander.Header> <DockPanel> <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/> <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/> </DockPanel> </Expander.Header> <Expander.Content> <ItemsPresenter /> </Expander.Content> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> <!-- Style for groups under the top level. --> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <DockPanel Background="LightBlue"> <TextBlock Text="{Binding Path=Name, Converter={StaticResource completeConverter}}" Foreground="Blue" Margin="30,0,0,0" Width="100"/> <TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/> </DockPanel> </DataTemplate> </GroupStyle.HeaderTemplate> </GroupStyle> </DataGrid.GroupStyle>
DataGrid 'de öğeleri sıralama
Öğelerin bir içinde nasıl sıralanacağını belirtmek için DataGrid , SortDescription türü kaynak görünümündeki öğeleri sıralamak üzere kullanın.
DataGrid 'deki öğeleri sıralamak için
SortDescriptionSıralama ölçütü olacak özelliği belirten bir oluştur. Özelliği XAML 'de veya kodda belirtebilirsiniz.
XAML 'de, öğesini PropertyName sıralama yapılacak özelliğin adına ayarlayın.
Kod ' da, ' a ve ' a göre sıralanacak özelliğin adını geçirin ListSortDirection .
Öğesini SortDescriptionCollectionViewSource.SortDescriptions koleksiyona ekleyin.
SortDescriptionSortDescriptions Ek özelliklere göre sıralamak için koleksiyona ek örnekler ekleyin.
<CollectionViewSource.SortDescriptions> <!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"' declaration. --> <scm:SortDescription PropertyName="ProjectName"/> <scm:SortDescription PropertyName="Complete" /> <scm:SortDescription PropertyName="DueDate" /> </CollectionViewSource.SortDescriptions>// Requires using System.ComponentModel; ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource); if (cvTasks != null && cvTasks.CanSort == true) { cvTasks.SortDescriptions.Clear(); cvTasks.SortDescriptions.Add(new SortDescription("ProjectName", ListSortDirection.Ascending)); cvTasks.SortDescriptions.Add(new SortDescription("Complete", ListSortDirection.Ascending)); cvTasks.SortDescriptions.Add(new SortDescription("DueDate", ListSortDirection.Ascending)); }Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource) If cvTasks IsNot Nothing And cvTasks.CanSort = True Then cvTasks.SortDescriptions.Clear() cvTasks.SortDescriptions.Add(New SortDescription("ProjectName", ListSortDirection.Ascending)) cvTasks.SortDescriptions.Add(New SortDescription("Complete", ListSortDirection.Ascending)) cvTasks.SortDescriptions.Add(New SortDescription("DueDate", ListSortDirection.Ascending)) End If
DataGrid 'de öğeleri filtreleme
Bir kullanarak içindeki öğeleri filtrelemek için DataGridCollectionViewSource , etkinliğin işleyicisinde filtreleme mantığını sağlarsınız CollectionViewSource.Filter .
DataGrid 'deki öğeleri filtrelemek için
Olay için bir işleyici ekleyin CollectionViewSource.Filter .
FilterOlay işleyicisinde filtreleme mantığını tanımlayın.
Bu filtre, görünüm her yenilendiğinde uygulanır.
<CollectionViewSource x:Key="cvsTasks" Source="{StaticResource tasks}" Filter="CollectionViewSource_Filter">private void CollectionViewSource_Filter(object sender, FilterEventArgs e) { Task t = e.Item as Task; if (t != null) // If filter is turned on, filter completed items. { if (this.cbCompleteFilter.IsChecked == true && t.Complete == true) e.Accepted = false; else e.Accepted = true; } }Private Sub CollectionViewSource_Filter(ByVal sender As System.Object, ByVal e As System.Windows.Data.FilterEventArgs) Dim t As Task = e.Item If t IsNot Nothing Then ' If filter is turned on, filter completed items. If Me.cbCompleteFilter.IsChecked = True And t.Complete = True Then e.Accepted = False Else e.Accepted = True End If End If End Sub
Alternatif olarak, DataGrid filtreleme mantığını sağlayan ve CollectionView.Filter filtreyi uygulamak için özelliğini ayarlayarak bir yöntemi oluşturarak içindeki öğeleri filtreleyebilirsiniz. Bu yöntemin bir örneğini görmek için bkz. bir görünümdeki verileri filtreleme.
Örnek
Aşağıdaki örnek, içindeki verileri gruplandırma, sıralama ve filtreleme işlemlerini TaskCollectionViewSource ve içindeki gruplanmış, sıralanmış ve filtrelenmiş verileri görüntülemeyi gösterir TaskDataGrid . , CollectionViewSource İçin olarak kullanılır ItemsSourceDataGrid . Gruplandırma, sıralama ve filtreleme, üzerinde gerçekleştirilir CollectionViewSource ve DataGrid Kullanıcı arabiriminde görüntülenir.
Bu örneği test etmek için DGGroupSortFilterExample adını proje adınızla eşleşecek şekilde ayarlamanız gerekecektir. Visual Basic kullanıyorsanız, için sınıf adını Window aşağıdaki şekilde değiştirmeniz gerekir.
<Window x:Class="MainWindow"
<Window x:Class="DGGroupSortFilterExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DGGroupSortFilterExample"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="Group, Sort, and Filter Example" Height="575" Width="525">
<Window.Resources>
<local:CompleteConverter x:Key="completeConverter" />
<local:Tasks x:Key="tasks" />
<CollectionViewSource x:Key="cvsTasks" Source="{StaticResource tasks}"
Filter="CollectionViewSource_Filter">
<CollectionViewSource.SortDescriptions>
<!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"' declaration. -->
<scm:SortDescription PropertyName="ProjectName"/>
<scm:SortDescription PropertyName="Complete" />
<scm:SortDescription PropertyName="DueDate" />
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ProjectName"/>
<PropertyGroupDescription PropertyName="Complete"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<DataGrid x:Name="dataGrid1"
ItemsSource="{Binding Source={StaticResource cvsTasks}}"
CanUserAddRows="False">
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="#FF112255" BorderBrush="#FF002255" Foreground="#FFEEEEEE" BorderThickness="1,1,1,5">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups under the top level. -->
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="LightBlue">
<TextBlock Text="{Binding Path=Name, Converter={StaticResource completeConverter}}" Foreground="Blue" Margin="30,0,0,0" Width="100"/>
<TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBlock Text=" Filter completed items " VerticalAlignment="Center" />
<CheckBox x:Name="cbCompleteFilter" VerticalAlignment="Center"
Checked="CompleteFilter_Changed" Unchecked="CompleteFilter_Changed" />
<Button Content="Remove Groups" Margin="10,2,2,2" Click="UngroupButton_Click" />
<Button Content="Group by Project/Status" Margin="2" Click="GroupButton_Click" />
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace DGGroupSortFilterExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Get a reference to the tasks collection.
Tasks _tasks = (Tasks)this.Resources["tasks"];
// Generate some task data and add it to the task list.
for (int i = 1; i <= 14; i++)
{
_tasks.Add(new Task()
{
ProjectName = "Project " + ((i % 3) + 1).ToString(),
TaskName = "Task " + i.ToString(),
DueDate = DateTime.Now.AddDays(i),
Complete = (i % 2 == 0)
});
}
}
private void UngroupButton_Click(object sender, RoutedEventArgs e)
{
ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
if (cvTasks != null)
{
cvTasks.GroupDescriptions.Clear();
}
}
private void GroupButton_Click(object sender, RoutedEventArgs e)
{
ICollectionView cvTasks = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
if (cvTasks != null && cvTasks.CanGroup == true)
{
cvTasks.GroupDescriptions.Clear();
cvTasks.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName"));
cvTasks.GroupDescriptions.Add(new PropertyGroupDescription("Complete"));
}
}
private void CompleteFilter_Changed(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource).Refresh();
}
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
Task t = e.Item as Task;
if (t != null)
// If filter is turned on, filter completed items.
{
if (this.cbCompleteFilter.IsChecked == true && t.Complete == true)
e.Accepted = false;
else
e.Accepted = true;
}
}
}
[ValueConversion(typeof(Boolean), typeof(String))]
public class CompleteConverter : IValueConverter
{
// This converter changes the value of a Tasks Complete status from true/false to a string value of
// "Complete"/"Active" for use in the row group header.
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool complete = (bool)value;
if (complete)
return "Complete";
else
return "Active";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string strComplete = (string)value;
if (strComplete == "Complete")
return true;
else
return false;
}
}
// Task Class
// Requires using System.ComponentModel;
public class Task : 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;
// Data for undoing canceled edits.
private Task temp_Task = null;
private bool m_Editing = false;
// Public properties.
public string ProjectName
{
get { return this.m_ProjectName; }
set
{
if (value != this.m_ProjectName)
{
this.m_ProjectName = value;
NotifyPropertyChanged("ProjectName");
}
}
}
public string TaskName
{
get { return this.m_TaskName; }
set
{
if (value != this.m_TaskName)
{
this.m_TaskName = value;
NotifyPropertyChanged("TaskName");
}
}
}
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");
}
}
}
// 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;
m_Editing = false;
}
}
public void EndEdit()
{
if (m_Editing == true)
{
temp_Task = null;
m_Editing = false;
}
}
}
// Requires using System.Collections.ObjectModel;
public class Tasks : ObservableCollection<Task>
{
// Creating the Tasks collection in this way enables data binding from XAML.
}
}
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Class MainWindow
Public Sub New()
InitializeComponent()
' Get a reference to the tasks collection.
Dim _tasks As Tasks = Me.Resources("tasks")
' Generate some task data and add it to the task list.
For index = 1 To 14
_tasks.Add(New Task() With _
{.ProjectName = "Project " & ((index Mod 3) + 1).ToString(), _
.TaskName = "Task " & index.ToString(), _
.DueDate = Date.Now.AddDays(index), _
.Complete = (index Mod 2 = 0) _
})
Next
End Sub
Private Sub UngroupButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource)
If cvTasks IsNot Nothing Then
cvTasks.GroupDescriptions.Clear()
End If
End Sub
Private Sub GroupButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim cvTasks As ICollectionView = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource)
If cvTasks IsNot Nothing And cvTasks.CanGroup = True Then
cvTasks.GroupDescriptions.Clear()
cvTasks.GroupDescriptions.Add(New PropertyGroupDescription("ProjectName"))
cvTasks.GroupDescriptions.Add(New PropertyGroupDescription("Complete"))
End If
End Sub
Private Sub CompleteFilter_Changed(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
' Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource).Refresh()
End Sub
Private Sub CollectionViewSource_Filter(ByVal sender As System.Object, ByVal e As System.Windows.Data.FilterEventArgs)
Dim t As Task = e.Item
If t IsNot Nothing Then
' If filter is turned on, filter completed items.
If Me.cbCompleteFilter.IsChecked = True And t.Complete = True Then
e.Accepted = False
Else
e.Accepted = True
End If
End If
End Sub
End Class
Public Class CompleteConverter
Implements IValueConverter
' This converter changes the value of a Tasks Complete status from true/false to a string value of
' "Complete"/"Active" for use in the row group header.
Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Dim complete As Boolean = value
If complete = True Then
Return "Complete"
Else
Return "Active"
End If
End Function
Public Function ConvertBack1(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Dim strComplete As String = value
If strComplete = "Complete" Then
Return True
Else
Return False
End If
End Function
End Class
' Task class
' Requires Imports System.ComponentModel
Public Class Task
Implements 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 m_ProjectName As String = String.Empty
Private m_TaskName As String = String.Empty
Private m_DueDate As DateTime = Date.Now
Private m_Complete As Boolean = False
' Data for undoing canceled edits.
Private temp_Task As Task = Nothing
Private m_Editing As Boolean = False
' Public properties.
Public Property ProjectName() As String
Get
Return Me.m_ProjectName
End Get
Set(ByVal value As String)
If Not value = Me.m_ProjectName Then
Me.m_ProjectName = value
NotifyPropertyChanged("ProjectName")
End If
End Set
End Property
Public Property TaskName() As String
Get
Return Me.m_TaskName
End Get
Set(ByVal value As String)
If Not value = Me.m_TaskName Then
Me.m_TaskName = value
NotifyPropertyChanged("TaskName")
End If
End Set
End Property
Public Property DueDate() As Date
Get
Return Me.m_DueDate
End Get
Set(ByVal value As Date)
If Not value = Me.m_DueDate Then
Me.m_DueDate = value
NotifyPropertyChanged("DueDate")
End If
End Set
End Property
Public Property Complete() As Boolean
Get
Return Me.m_Complete
End Get
Set(ByVal value As Boolean)
If Not value = Me.m_Complete Then
Me.m_Complete = value
NotifyPropertyChanged("Complete")
End If
End Set
End Property
' Implement INotifyPropertyChanged interface.
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Sub NotifyPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
' Implement IEditableObject interface.
Public Sub BeginEdit() Implements IEditableObject.BeginEdit
If Not Me.m_Editing Then
Me.temp_Task = Me.MemberwiseClone()
Me.m_Editing = True
End If
End Sub
Public Sub CancelEdit() Implements IEditableObject.CancelEdit
If m_Editing = True Then
Me.ProjectName = Me.temp_Task.ProjectName
Me.TaskName = Me.temp_Task.TaskName
Me.DueDate = Me.temp_Task.DueDate
Me.Complete = Me.temp_Task.Complete
Me.m_Editing = False
End If
End Sub
Public Sub EndEdit() Implements IEditableObject.EndEdit
If m_Editing = True Then
Me.temp_Task = Nothing
Me.m_Editing = False
End If
End Sub
End Class
' Requires Imports System.Collections.ObjectModel
Public Class Tasks
Inherits ObservableCollection(Of Task)
' Creating the Tasks collection in this way enables data binding from XAML.
End Class