Reputation: 35
So I want to check 2 ObservableCollections
if they equals each other.
If so, then return Nothing Changed
(collection1 and collection2 are the same).
Otherwise return Something Changed
.
The problem now is, that both collection contains the same values even when I change items from collection 2.
I posted some Code and gif
of the Debug result to show you what I get.
I dont understand, why both Collections are the same after clicking the Save Button.
ViewModel
In my ViewModel I have:
1 ObservableCollection
called RightsCollection
.
This should contain the rights on my XAML which I can change via ToggleButton
.
1 Employee
class where a ObservableCollection<Groups>
is located and inside of the Groups.Col
there is a ObservableCollection<Rights>
which contains the default group rights which was loaded from DataBase which cant be changed.
Note: My get
set
is always the same. They just have other names and DataTypes consider to its field datatype.
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).
Employee Class
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).
}
Rights Class
private int _rightId;
private string _rightName;
private bool _hasRight;
// Again get set is same
Groups Class
private int _groupId;
private string _groupName;
private ObservableCollection<Rights> _rights;
// Again, same Get/Set like always
XAML
In my XAML I have:
a ComboBox
. ComboBox.ItemsSource
bind to GroupsCollection
. ComboBox.SelectedValue
bind to SingleEmployee.Group
.
So while changing the ComboBox, the Group of the Single Employee will be set.
This ComboBox
also got an SelectionChanged
Event where I set the RightsCollection
equal to SingleEmployee.Group.Rights
. So that both contains the same items/values now.
It also contains an ItemsControl
where I can set the rights myself (and where the rights will be loaded when ComboBox.SelectionChanged
(which works).
<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 Event in Code-Behind
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("################################################");
Set ViewModel in Code-Behind
private readonly EmployeeViewModel _viewModel;
// constructor...
{
_viewModel = (EmployeeViewModel) DataContext;
}
Save Button Command Method
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 Event
// 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
After Button Click
After Button Click
Upvotes: 0
Views: 104
Reputation: 35
I fixed this problem in my SelectionChanged Event
deleting this line:
_viewModel.RightsCollection = _viewModel.SingleEmployee.Group.Rights;
and replaced it with this:
for (int i = 0; i < _viewModel.SingleEmployee.Group.Rights.Count; i++)
{
if (_viewModel.SingleEmployee.Group.Rights[i].HasRight != _viewModel.RightsCollection[i].HasRight)
{
_viewModel.RightsCollection[i].HasRight = _viewModel.SingleEmployee.Group.Rights[i].HasRight;
}
}
Because both collections are nearly the same, they will always have the same amount of items so I can use a for
-loop.
If a value is not the same, then the value will change.
This way I don't create a reflection (I guess) so it's working.
The only thing now is, that
bool equal = RightsCollection.Count == SingleEmployee.Group.Rights.Count && RightsCollection.All(x => SingleEmployee.Group.Rights.Contains(x));
isn't working but I will use a for-loop here too which checks if the items contains the same value, if not then "Something changed"
.
Upvotes: 0
Reputation: 21
_viewModel.RightsCollection = _viewModel.SingleEmployee.Group.Rights;
the left collection has the same reference of the right collection. So, if you change one collection it will reflect in the other collection.
ObservableCollection<Whatever> _viewModel.RightsCollection = new ObservableCollection<Whatever>();
foreach(var item in _viewModel.SingleEmployee.Group.Rights)
_viewModel.RightsCollection.Add(item);
Upvotes: 2