mcavanaugh418
mcavanaugh418

Reputation: 127

Trying to sort a datagrid that is consistantly being updated

I have a datagrid in my WPF program that is updating its data every three seconds. When this happens the sorting of this datagrid resets back to its default. I have 4 Columns, three of which I would like to be sorted. the columns are Name, Aux, Time, and State. I would like the sorting to work in this order:

State Ascending

Aux Descending

Time Descending

I have tried adding sorting in a few different ways programmically but I have been unable to add my datagrid as a resource (I've never done this before) and collectionviewsource in the XAML doesn't work like someone else said it would. It doesn't affect the sorting at all.

here is my datagrid

<DataGrid Name="DataGrid" AutoGenerateColumns="False" IsReadOnly="True" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" ColumnWidth="*"  Foreground="Green" FontSize="10" ItemsSource="{Binding Path=mylist, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  Loaded="textBlock_Loaded" Margin="0,10" RenderTransformOrigin="0.127,0.275" Background="{x:Null}" IsSynchronizedWithCurrentItem="False" GridLinesVisibility="Horizontal">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding AgentName}"  />
                    <DataGridTextColumn Header="State" Binding="{Binding AgentState}"  />
                    <DataGridTextColumn Header="Aux" Binding="{Binding AuxReasons}" />
                    <DataGridTextColumn Header="Time" Binding="{Binding AgentDateTimeStateChange, StringFormat={}{0:hh}:{0:mm}:{0:ss}}"/>                                          
                </DataGrid.Columns>
            </DataGrid>

I think this would work if I could figure out how to get DataGrid as a resource so find resource can access the DataGrid

   if (e.CmsData != null)
            {
                List<NewAgent> newAgentList = new List<NewAgent>();                    

                Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
                {                                         
                    foreach (var item in e.CmsData.Agents)
                    {
                        NewAgent newAgents = new ScoreBoardClientTest.NewAgent();

                        newAgents.AgentName = item.AgName;

                        newAgents.AgentExtension = item.Extension;

                        newAgents.AgentDateTimeChange = ConvertedDateTimeUpdated;

                        newAgents.AuxReasons = item.AuxReasonDescription;

                        newAgents.LoginIdentifier = item.LoginId;

                        newAgents.AgentState = item.WorkModeDirectionDescription;

                        var timeSpanSince = DateTime.Now - item.DateTimeUpdated;
                        newAgents.AgentDateTimeStateChange = timeSpanSince;                    

                        newAgentList.Add(newAgents);


                    }
                    if (DataGrid.ItemsSource != null)
                    {
                        //This is the line that your are missing
                        var myViewSource = DataGrid.ItemsSource as CollectionViewSource;

                        myViewSource.SortDescriptions.Add(new SortDescription("AgentState", ListSortDirection.Ascending));
                        myViewSource.SortDescriptions.Add(new SortDescription("AuxReasons", ListSortDirection.Descending));
                        myViewSource.SortDescriptions.Add(new SortDescription("AgentDateTimeStateChange", ListSortDirection.Descending));
                    }

                    DataGrid.ItemsSource = newAgentList;                       
                }));                    
            }

my objects defined in a NewAgent class

class NewAgent
    {
        public string AgentName { get; set; }
        public int AgentExtension { get; set; }
        public TimeSpan AgentDateTimeChange { get; set; }
        public TimeSpan AgentDateTimeStateChange { get; set; }
        public String AuxReasons { get; set; }
        public string LoginIdentifier { get; set; }
        public string AgentState { get; set; }

    }

Upvotes: 0

Views: 52

Answers (1)

Daniel Marques
Daniel Marques

Reputation: 703

Actually, you need to get the ItemsSource of your DataGrid and not the DataGrid itself. Like that:

if (DataGrid.ItemsSource != null)
{
    //This is the line that your are missing
    var myViewSource = DataGrid.ItemsSource as CollectionViewSource;

    myViewSource.SortDescriptions.Add(new SortDescription("AgentState", ListSortDirection.Ascending));
    myViewSource.SortDescriptions.Add(new SortDescription("AuxReasons", ListSortDirection.Descending));
    myViewSource.SortDescriptions.Add(new SortDescription("AgentDateTimeStateChange", ListSortDirection.Descending));
}

Also make sure that the first parameter of the constructor of SortDescription matches the name of the property that you would like to sort the objects in your collection by ("AgentState", "AuxReasons" and "AgentDateTimeStateChange" in your example).

Since you edited your question with more information, here's what you need to do:

Instead of setting the ItemsSource of your DataGrid to be a list of NewAgent, set it to be a ListCollectionView of your list. Only then you will be able to sort that collection.

So:

//Create a ListCollectionView of your List of new agents
ListCollectionView myListCollectionView = new ListCollectionView(newAgentList);

//Sort your collection view
myListCollectionView .SortDescriptions.Add(new SortDescription("AgentState", ListSortDirection.Ascending));
myListCollectionView .SortDescriptions.Add(new SortDescription("AuxReasons", ListSortDirection.Descending));
myListCollectionView .SortDescriptions.Add(new SortDescription("AgentDateTimeStateChange", ListSortDirection.Descending));

//Bind your data
DataGrid.ItemsSource = myCollectionView;

Upvotes: 1

Related Questions