0
votes

I am trying to have a datagrid display a sorted collection the first time it is loaded. The datagrid loads fine if I do not try to sort it but as soon as I put in a CollectionViewSource in, nothing loads to the datagrid. What am I missing in the below code that will load the collection and have it sorted?

Here is the XAML

   <Window.Resources>
        <CollectionViewSource Source="{Binding TdStatusCol}" x:Key="StatusItems">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="RegionNm" Direction="Ascending"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
.....
    <DataGrid x:Name="dgThreads" ItemsSource="{Binding Source={StaticResource StatusItems}}" AutoGenerateColumns="False" Margin="10,5,10,5" 
              RenderTransformOrigin="0.487,-0.31" AlternatingRowBackground="#FFB5CFA7" 
              CanUserAddRows="False" CanUserDeleteRows="False" Grid.Row="1" Grid.Column="0" Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="colRegionNm" Header = "Region Name" Binding="{Binding RegionNm}"/>
            <DataGridTextColumn x:Name="colStatus" Header = "Status" Binding="{Binding Status}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="{x:Type DataGridCell}">
                        <Setter Property="Background" Value="{Binding StatusChange}"/>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn x:Name="colThdState" Header = "Thread State" Binding="{Binding ThdState}" Visibility="Hidden">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="{x:Type DataGridCell}">
                        <Setter Property="Background" Value="{Binding ThdStateChange}"/>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn x:Name="colAction" Header = "Action" Binding="{Binding Action}" Visibility="Hidden">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="{x:Type DataGridCell}">
                        <Setter Property="Background" Value="{Binding ActionChange}"/>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn x:Name="colFilesProcessed" Header = "Files Processed" Binding="{Binding FilesProcessed}"/>
            <DataGridTextColumn x:Name="colNumErrors" Header = "Number of Errors" Binding="{Binding NumErrors}"/>
            <DataGridTextColumn x:Name="colLastUpdated" Header = "Last Updated" Binding="{Binding LastUpdated}"/>
        </DataGrid.Columns>
    </DataGrid>

Here is the CS code:

public partial class MainWindow : Window
{
        public ObservableCollection<TStatus> TdStatusCol { get; set; }
        public MainWindow()
        {
            TdStatusCol = new ObservableCollection<TStatus>();
            TdStatusCol.Add(new TStatus()
            {
                RegionNm = "Second",
                Status = "------",
                ThdState = "------",
                Action = "------",
                FilesProcessed = "------",
                NumErrors = "------",
                LastUpdated = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")
            });
            TdStatusCol.Add(new TStatus()
            {
                RegionNm = "Third",
                Status = "------",
                ThdState = "------",
                Action = "------",
                FilesProcessed = "------",
                NumErrors = "------",
                LastUpdated = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")
            });
            TdStatusCol.Add(new TStatus()
            {
                RegionNm = "First",
                Status = "------",
                ThdState = "------",
                Action = "------",
                FilesProcessed = "------",
                NumErrors = "------",
                LastUpdated = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")
            });
        }
}

public class TStatus : INotifyPropertyChanged
{
    private string
        _status,
        _action,
        _thdstate,
        _filesprocessed,
        _numerrors,
        _lastupdated;
    public string RegionNm { get; set; }
    public string Status
    {
        get { return _status; }
        set
        {
            if(_status != value)
            {
                _status = value;
                RaisePropertyChanged("Status");
                RaisePropertyChanged("StatusChange");
            }
        }
    }
    public Brush StatusChange
    {
        get
        {
            switch(_status)
            {
                case "Running":
                    return Brushes.LightGreen;
                case "Closed":
                    return Brushes.LightPink;
                case "Errored":
                    return Brushes.Red;
                default:
                    return Brushes.LightYellow;
            }
        }
    }
    public string Action
    {
        get { return _action; }
        set
        {
            _action = value;
            RaisePropertyChanged("Action");

        }
    }
    public Brush ActionChange
    {
        get
        {
            switch (_action)
            {
                case "Run":
                    return Brushes.LightGreen;
                case "Stop":
                    return Brushes.LightPink;
                default:
                    return Brushes.LightYellow;
            }
        }
    }
    public string ThdState
    {
        get { return _thdstate; }
        set
        {
            _thdstate = value;
            RaisePropertyChanged("ThdState");

        }
    }
    public Brush ThdStateChange
    {
        get
        {
            switch (_thdstate)
            {
                case "Running":
                    return Brushes.LightGreen;
                case "Closed":
                    return Brushes.LightPink;
                case "Errored":
                    return Brushes.Red;
                default:
                    return Brushes.LightYellow;
            }
        }
    }
    public string FilesProcessed
    {
        get { return _filesprocessed; }
        set
        {
            _filesprocessed = value;
            RaisePropertyChanged("FilesProcessed");

        }
    }
    public string NumErrors
    {
        get { return _numerrors; }
        set
        {
            _numerrors = value;
            RaisePropertyChanged("NumErrors");

        }
    }
    public string LastUpdated
    {
        get {return _lastupdated;}
        set
        {
            _lastupdated = value;
            RaisePropertyChanged("LastUpdated");

        }
    }
private void RaisePropertyChanged(string propertyName)
{
    var handler = PropertyChanged;
    if (handler == null) return;

    handler(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}

Update: I have followed another post and removed the CollectionViewSource in the XAML. Set the DataGrid ItemSource = "{Binding TdStatusCol}" and added the following code to CS code

public ICollectionView StatusView { get; set; }

In Public MainWindow() added:

StatusView = CollectionViewSource.GetDefaultView(TdStatusCol);
StatusView.SortDescriptions.Add(new SortDescription("RegionNm", ListSortDirection.Ascending));

Why does second option work over the first and which one is better code logic? Thanks

1

1 Answers

0
votes

Bind to the view, not the collection:

DataGrid ItemSource = "{Binding TdStatusCol.View}"