Как разделить две группы, сгруппированные по заголовкам, а также по времени появления в C# WPF CollectionView? - PullRequest
1 голос
/ 02 марта 2020

Поэтому я использую CollectionView для группировки похожих данных. Из приведенного ниже кода вы можете видеть, что у меня есть класс с идентификатором и другой класс, который содержит метку времени, заголовок и сообщение.

Так что, если есть пустая коллекция, и я сгенерирую Название A в 07:30:01, это создаст группу. Если я сгенерирую сразу после этого еще один заголовок А в 07:30:03, то он должен сгруппироваться вместе с предыдущим, потому что это один и тот же заголовок. Теперь, если я сгенерирую Заголовок B в 07:30:10, тогда он должен создать другую группу, потому что существующий заголовок и этот заголовок отличаются. И если сразу после этого я сгенерирую еще один заголовок B, он будет сгруппирован с заголовком B.

Мое намерение состоит в том, чтобы в то время как я хочу продолжать группировать его на основе заголовка, если последняя запись была заголовком B в 07 : 30: 15 AM, и новая запись - Титул А в 07:31:00. Я хочу, чтобы эта запись была новой группой, а не группировалась в существующие Титулы А. Я смог добиться этого, заказав его по идентификатору, который вы видите ниже:

enter image description here

Но, как вы можете видеть, я не хочу этих 0,1,2,3 написано там, я хочу заголовок, который сгруппирован по написанному там. Есть ли способ сделать это?

Вот мой код:

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));
            }
        }
    }
}

1 Ответ

1 голос
/ 02 марта 2020

Вместо привязки к Name сделать привязку к первому элементу Items, все они имеют одинаковые 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>
...