Sum
Sum

Reputation: 1

How to synchronize two datagrids in WPF (.NET Framework)?

I have two datagrids in my project. One of them is the main grid and the other is filtered version of the main grid. When I run my project, I can get the datas from excel file and successfully perform the filtering operation. The problem is; I have multiple tabs and when I switch between the tabs, my filtered data grid stays the same. I have to click a button to switch new datas. What I want is changing the filtered grid simultaneously when the main grid changes. I use MVVM structure and binding. My view model is like that:

public List<MyEntity> List { get; set; } = new List<MyEntity>(); //For main datagrid
public List<MyEntity> TempList { get; set; } = new List<MyEntity>(); // For filtered datagrid

public ICommand AddCommand { get; set; }
public ICommand FilteredListCommand{ get; set; }

public TolType SelectedTolType { get; set; } //Every tab keeps different type excel file. So I control them with enum. TolType is the enum.

public ViewModel()
{
}

private void MainList(object obj)
{
            List.Clear();
            TempList.Clear();

            SelectedTolType = (TolType)obj;
            List = genelManager.GetAll(SelectedTolType);

            OnPropertyChanged(nameof(List));
}

private void FiteredList(object obj)
{
            if (SelectedTolType == 0) return;
            TempList = List.FindAll(x => x.OkNotOk == false);
            
            OnPropertyChanged(nameof(TempList));
}

And my XAML is like that:

<StackPanel>

<DataGrid x:Name="dg1" ItemsSource="{Binding List}"/> 
<DataGrid x:Name="dg2" ItemsSource="{Binding List}"/>

<ToggleButton Content="First Tab"
              Command="{Binding AddCommand}"
              CommandParameter="{x:Static local:TolType.Tab1}"/> 
<ToggleButton Content="Second Tab"
              Command="{Binding AddCommand}" 
              CommandParameter="{x:Static locad:TolType.Tab2}"/>
 
<ToggleButton Content="Filter"
              Command="{Binding FilteredListCommand}">
 
</StackPanel>

I tried to change my FilteredListCommand prop but somehow I couldn't figure it out.

Upvotes: 0

Views: 218

Answers (1)

BionicCode
BionicCode

Reputation: 28968

When you need to sort, group or filter data for displaying in the view, always use the ICollectionView of the original collection to perform such actions. Modifying the collection view will not modify the underlying collection. See Binding to collections to learn more.

Additionally, use an ObservableCollection. If you plan to modify the source collection use ObservableCollection. Then Add or Remove items instead of overwriting the collection instance.

To solve your problem, you must introduce a new collection view that you can bind the filtered DataGrid to. Updating the underlying collection will also update the view.

ViewModel.cs

public ObservableCollection<MyEntity> List { get; }
public ICollectionView FilteredListView { get; }

public ViewModel()
{
  this.List = new ObservableCollection<MyEntity>();
  this.FilteredListView = new ListCollectionView(this.List);
}

private void UpdateList(object obj)
{
  List.Clear();
  SelectedTolType = (TolType)obj;
  IEnumerable<MyEntity> newItems = genelManager.GetAll(SelectedTolType);

  // Since FilteredListView is a ICollectionView of List,
  // modifying List will also modify FilteredListView.
  foreach (var item in newItems)
  {
    this.List.Add(item);
  }
}

private void FilterList(object obj)
{
  if (SelectedTolType == 0) 
    return;

  this.FilteredListView.Filter = item => !(item as MyEntity).OkNotOk;
}

MainWindow.xaml

<DataGrid ItemsSource="{Binding List}" /> 
<DataGrid ItemsSource="{Binding FilteredListView}" />

Upvotes: 2

Related Questions