Search code examples
c#wpfwpfdatagrid

How to keep my selection to the DataGrid Row after refresh the data grid using timer in WPF


I have WPF DataGrid and i am binding the DataGrid but if any changes made into the Data it will automatically refresh but my selection to the datagrid row will unselected.


Solution

  • Instead of using a List to store the data, try using an ObservableCollection. The advantage of using the ObservableCollection is that whenever you add an item to the collection the UI get automatically updated so a manually refresh of the DataGrid is not required. Below I have shared a sample application that adds and updates record in the DataGrid.

    XAML:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <RadioButton Name="CBAdd" GroupName="AddOrEdit" Content="Add Messages" IsChecked="True"></RadioButton>
            <RadioButton Name="CBUpdate" GroupName="AddOrEdit" Content="Update Messages"></RadioButton>
        </StackPanel>
        <DataGrid Grid.Row="1" Name="DGNew" CanUserAddRows="False">
    
        </DataGrid>
    </Grid>
    

    Code Behind:

    using System;
    using System.Windows;
    using System.Timers;
    using System.Collections.ObjectModel;
    using System.Windows.Threading;
    using System.ComponentModel;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            Timer _timer = null;
            ObservableCollection<CustomMessage> _messages = null;
    
            int count = 0;
    
            public MainWindow()
            {
                InitializeComponent();
                _messages = new ObservableCollection<CustomMessage>();
                count++;
                _messages.Add(new CustomMessage() { ID = count, Message = "Message" });
                _timer = new Timer(1000);
                _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
    
                this.DGNew.ItemsSource = _messages;
                _timer.Start();
            }
    
            void _timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                try
                {
                    _timer.Stop();
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
                    {
                        if (this.CBAdd.IsChecked == true)
                        {
                            count++;
                            _messages.Add(new CustomMessage() { ID = count, Message = "Timer Message " + count });
                        }
                        else
                        {
                            // Udpate existing Message
                            Random random = new Random();
                            CustomMessage message = _messages[random.Next(0, count)];
                            message.Message = "Updated Time" + DateTime.Now.ToLongTimeString();
                        }
                    }));
                }
                finally
                {
                    _timer.Start();
                }
            }
        }
    
        public class CustomMessage : INotifyPropertyChanged
        {
            private int _ID;
    
            public int ID
            {
                get { return _ID; }
                set
                {
                    _ID = value;
                    OnPropertyChanged("ID");
                }
            }
    
            private string _Message;
    
            public string Message
            {
                get { return _Message; }
                set
                {
                    _Message = value;
                    OnPropertyChanged("Message");
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }