Что я хочу
Итак, я хочу проверить 2 ObservableCollections
, равны ли они друг другу.
Если это так, верните Nothing Changed
(collection1 и collection2 одинаковы).
В противном случае верните Something Changed
.
Проблема
Проблема в том, что обе коллекции содержат одинаковые значения, даже когда я изменяю элементы из коллекции 2.
Я опубликовал некоторый код и gif
результата отладки, чтобы показать вам, что я получаю.
Я не понимаю, почему обе коллекции одинаковые после нажатия кнопки «Сохранить».
код
ViewModel
В моей ViewModel у меня есть:
1 ObservableCollection
называется RightsCollection
.
Это должно содержать права на мой XAML, которые я могу изменить с помощью ToggleButton
.
1 Employee
класс, где расположен ObservableCollection<Groups>
, а внутри Groups.Col
есть ObservableCollection<Rights>
, который содержит права группы по умолчанию, которые были загружены из базы данных, которые не могут быть изменены.
Примечание: мои get
set
всегда одинаковы. У них просто есть другие имена, и DataTypes считают его тип данных поля.
private Employee _singleEmployee = new Employee();
public Employee SingleEmployee
{
get => _singleEmployee;
set
{
if (_singleEmployee == value) return;
_singleEmployee = value;
OnPropertyChanged("SingleEmployee");
}
}
private ObservableCollection<Groups> _groupsCollection = new ObservableCollection<Groups>();
// public get set GroupsCollection (same like first).
private ObservableCollection<Rights> _rightsCollection = new ObservableCollection<Rights>();
// public get set RightsCollection (same like first).
Класс сотрудника
public class Employee : INotifyPropertyChanged
{
private int _employeeId;
private string _firstName;
private Groups _group = new Group();
// public get set EmployeeId (Same like first).
// public get set Group (same like first).
}
Класс прав
private int _rightId;
private string _rightName;
private bool _hasRight;
// Again get set is same
Группы Класс
private int _groupId;
private string _groupName;
private ObservableCollection<Rights> _rights;
// Again, same Get/Set like always
XAML
В моем XAML у меня есть:
ComboBox
. ComboBox.ItemsSource
привязать к GroupsCollection
. ComboBox.SelectedValue
привязка к SingleEmployee.Group
.
Таким образом, при изменении ComboBox будет установлена группа одного сотрудника.
Этот ComboBox
также получил SelectionChanged
Событие, где я установил RightsCollection
равным SingleEmployee.Group.Rights
. Так что теперь оба содержат одинаковые элементы / значения.
Он также содержит ItemsControl
, где я могу установить права самостоятельно (и где права будут загружены, когда ComboBox.SelectionChanged
(что работает).
<ComboBox x:Name="GroupComboBox" ItemsSource="{Binding GroupsCollection}" SelectedValue="{Binding SingleEmployee.Group}" DisplayMemberPath="GroupName" SelectionChanged="GroupComboBox_SelectionChanged">
ItemsControl
<ItemsControl ItemsSource="{Binding RightsCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<DockPanel>
<ToggleButton DockPanel.Dock="Right" Margin="10" IsChecked="{Binding HasRight}"/>
<TextBlock FontSize="15" FontWeight="Bold" Text="{Binding RightName}" DockPanel.Dock="Left" Margin="10" />
</DockPanel>
<TextBlock Text="{Binding RightsDesc}" Margin="30 0 0 10" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Событие SelectionChanged в коде позади
Debug.WriteLine("############ SelectionChanged Event ############");
Debug.WriteLine("# Before Change ##");
Debug.WriteLine($"SingleEmployee.Group.Rights.Count: {_viewModel.SingleEmployee.Group.Rights.Count} | RightsCollection.Count: {_viewModel.RightsCollection.Count}");
for (int i = 0; i < _viewModel.SingleEmployee.Group.Rights.Count; i++)
{
Debug.WriteLine($"Name: {_viewModel.SingleEmployee.Group.Rights[i].RightName}, HasRight: {_viewModel.SingleEmployee.Group.Rights[i].HasRight} || Name: {_viewModel.RightsCollection[i].RightName}, HasRight: {_viewModel.RightsCollection[i].HasRight}");
}
_viewModel.RightsCollection = _viewModel.SingleEmployee.Group.Rights;
Debug.WriteLine("# After Change #");
Debug.WriteLine($"SingleEmployee.Group.Rights.Count: {_viewModel.SingleEmployee.Group.Rights.Count} | RightsCollection.Count: {_viewModel.RightsCollection.Count}");
for (int i = 0; i < _viewModel.SingleEmployee.Group.Rights.Count; i++)
{
Debug.WriteLine$"Name: {_viewModel.SingleEmployee.Group.Rights[i].RightName}, HasRight: {_viewModel.SingleEmployee.Group.Rights[i].HasRight} || Name: {_viewModel.RightsCollection[i].RightName}, HasRight: {_viewModel.RightsCollection[i].HasRight}");
}
Debug.WriteLine("########## SelectionChanged Event END ##########");
Debug.WriteLine("################################################");
Установить ViewModel в Code-Behind
private readonly EmployeeViewModel _viewModel;
// constructor...
{
_viewModel = (EmployeeViewModel) DataContext;
}
Метод команды кнопки сохранения
Debug.WriteLine("############## After Button Click ##############");
for (int i = 0; i < RightsCollection.Count; i++)
{
Debug.WriteLine($"Name: {SingleEmployee.Group.Rights[i].RightName}, HasRight: {SingleEmployee.Group.Rights[i].HasRight} || Name: {RightsCollection[i].RightName}, HasRight: {RightsCollection[i].HasRight}");
}
Debug.WriteLine("################################################");
bool equal = RightsCollection.Count == SingleEmployee.Group.Rights.Count && RightsCollection.All(x => SSingleEmployee.Group.Rights.Contains(x));
Debug.WriteLine(equal ? "Nothing Changed" : "Something changed");
Что я пробовал
Событие SelectionChanged
// No Success
var collection = new ObservableCollection<Rights>(_viewModel.SingleEmployee.Group.Rights);
_viewModel.RightsCollection = collection;
.
// No Success
foreach(var item in _viewModel.SingleEmployee.Group.Rights)
_viewModel.RightsCollection.Add(item);
Результат отладки
SelectionChangedResult
|
SelectionChangedResult
![SelectionChangedResult (Picture)](https://i.stack.imgur.com/4qYe8.png)
после нажатия кнопки
![After Button Click (GIF)](https://i.stack.imgur.com/SGaWI.gif)
после нажатия кнопки
![After Button Click (Picture)](https://i.stack.imgur.com/XRvah.png)