所以我想检查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>
,其中包含从DataBase加载的默认组权限,不能改变了。
注意:我的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
也有一个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
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
单击按钮后
单击按钮后
答案 0 :(得分:2)
_viewModel.RightsCollection = _viewModel.SingleEmployee.Group.Rights;
左集合与右集合具有相同的引用。 因此,如果更改一个集合,它将反映在另一个集合中。
ObservableCollection<Whatever> _viewModel.RightsCollection = new ObservableCollection<Whatever>();
foreach(var item in _viewModel.SingleEmployee.Group.Rights)
_viewModel.RightsCollection.Add(item);
答案 1 :(得分:0)
我在SelectionChanged Event
中删除了以下行,解决了此问题:
_viewModel.RightsCollection = _viewModel.SingleEmployee.Group.Rights;
并替换为:
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;
}
}
因为两个集合几乎相同,所以它们将始终具有相同数量的项目,因此我可以使用for
循环。
如果值不相同,则该值将更改。
这样,我不创建反射(我想),所以它起作用了。
现在唯一的是
bool equal = RightsCollection.Count == SingleEmployee.Group.Rights.Count && RightsCollection.All(x => SingleEmployee.Group.Rights.Contains(x));
不起作用,但我也会在此处使用for循环,该循环检查项目是否包含相同的值,如果不相同,则"Something changed"
。