So I am utilizing CollectionView to group similar data together. From my code below, you can see that I have a class that has an identifier and another class in it which holds the TimeStamp, Title, and Message.
So if there is an empty collection, and I generate Title A at 07:30:01 AM, this will create a group. If I generate right after that, another Title A at 07:30:03 AM, then it should group together with the previous one because they are the same title. Now if I generate Title B at 07:30:10 AM, then it should create another group because the existing title and this title are different. And if I generate another Title B right after that, it will be grouped with Title B.
My intention is that while I want to continue to group it based on title, if the last entry was Title B at 07:30:15 AM and the new entry is Title A at 07:31:00 AM, I want this entry to be a new group instead of grouping it to the existing Title A's. I was somewhat able to achieve this by ordering it through identifier which you can see below:
But as you can see, I do not want those 0,1,2,3 written there, I want the Title's that is grouped by written there. Is there a way to do that?
Here is my code:
Xaml:
<Window.Resources>
<local:LogStatusCollection x:Key="logKey" />
<CollectionViewSource x:Key="logCollection" Source="{DynamicResource logKey}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="TimeStamp" />
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Identifier" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DataGrid x:Name="dataGrid1"
DataContext="{DynamicResource logCollection}" ItemsSource="{Binding Path=.}"
CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Time Stamp" Binding="{Binding Path=StatusLog.TimeStamp}" Width="*"/>
<DataGridTextColumn Header="Title" Binding="{Binding Path=StatusLog.Title}" Width="*"/>
<DataGridTextColumn Header="Message" Binding="{Binding Path=StatusLog.Message}" Width="*"/>
</DataGrid.Columns>
<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, StringFormat=Count: {0}}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
C#:
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public LogStatusCollection logCollection { get; }
public MainWindow()
{
InitializeComponent();
logCollection = (LogStatusCollection)this.Resources["logKey"];
logCollection.Add(new LogStatus
{
Identifier = 0,
StatusLog = new Status { Title = "Title A", Message = "Message A", TimeStamp = DateTime.Now.ToString()}
});
logCollection.Add(new LogStatus
{
Identifier = 1,
StatusLog = new Status { Title = "Title B", Message = "Message B", TimeStamp = DateTime.Now.AddMinutes(1).ToString() }
});
logCollection.Add(new LogStatus
{
Identifier = 1,
StatusLog = new Status { Title = "Title B", Message = "Message B", TimeStamp = DateTime.Now.AddMinutes(5).ToString() }
});
logCollection.Add(new LogStatus
{
Identifier = 2,
StatusLog = new Status { Title = "Title A", Message = "Message A", TimeStamp = DateTime.Now.AddMinutes(7).ToString() }
});
logCollection.Add(new LogStatus
{
Identifier = 3,
StatusLog = new Status { Title = "Title B", Message = "Message B", TimeStamp = DateTime.Now.AddMinutes(12).ToString() }
});
logCollection.Add(new LogStatus
{
Identifier = 3,
StatusLog = new Status { Title = "Title B", Message = "Message B", TimeStamp = DateTime.Now.AddMinutes(15).ToString() }
});
}
}
public class LogStatusCollection : ObservableCollection<LogStatus> {
}
public class LogStatus : INotifyPropertyChanged
{
private int _identifier = 0;
private Status _status;
public int Identifier
{
get { return _identifier; }
set
{
if (_identifier != value)
{
_identifier = value;
NotifyPropertyChanged("Identifier");
}
}
}
public Status StatusLog
{
get { return _status; }
set
{
if (_status != value)
{
_status = value;
NotifyPropertyChanged("Status");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Status : INotifyPropertyChanged
{
private string _timestamp;
private string _title;
private string _message;
public string TimeStamp
{
get { return _timestamp; }
set
{
if(_timestamp != value)
{
_timestamp = value;
NotifyPropertyChanged("TimeStamp");
}
}
}
public string Title
{
get { return _title; }
set
{
if (_title != value)
{
_title = value;
NotifyPropertyChanged("Title");
}
}
}
public string Message
{
get { return _message; }
set
{
if (_message != value)
{
_message = value;
NotifyPropertyChanged("Message");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Instead of binding to the Name
do bind to the first element of Items
, all of them have the same Title
:
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Items[0].StatusLog.Title}" Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount, StringFormat=Count: {0}}"/>
</DockPanel>
</Expander.Header>