C# ItemsControl与其items源-Gridbox不一致
我试图通过删除从数据库填充的另一个DataGrid中的项来填充DataGrid。 从原始版本中删除它们似乎可以完美地工作,但AllItems.Remove(allItem)似乎会引起问题。 每当我在左边的网格上单击Add时,右边的网格就会被一个填充。当我第二次尝试它时,它什么也不做,第三次它与这条线崩溃 未处理的异常:System.InvalidOperationException:一个ItemsControl 与其项目源不一致。有关详细信息,请参见内部异常 更多信息。-->系统异常:开发者信息 (使用文本可视化工具读取此):引发此异常是因为 控件“System.Windows.Controls.DataGrid”的生成器 Items.Count:名为'AddedItemsGrid'的3'已收到 CollectionChanged事件与的当前状态不一致 项目集合。检测到以下差异:C# ItemsControl与其items源-Gridbox不一致,c#,wpf,windows,C#,Wpf,Windows,我试图通过删除从数据库填充的另一个DataGrid中的项来填充DataGrid。 从原始版本中删除它们似乎可以完美地工作,但AllItems.Remove(allItem)似乎会引起问题。 每当我在左边的网格上单击Add时,右边的网格就会被一个填充。当我第二次尝试它时,它什么也不做,第三次它与这条线崩溃 未处理的异常:System.InvalidOperationException:一个ItemsControl 与其项目源不一致。有关详细信息,请参见内部异常 更多信息。-->系统异常:开发者信息
累计计数2与实际计数3不同。[累计 计数为(上次重置时计数+#添加-#自上次重置后删除)。] 如果你不完全理解我的意图,这里有一个简单的解释:
- LeftGrid由数据库填充
- RightGrid通过单击LeftGrid上的add按钮填充,同时项目也从RightGrid中删除
- 单击Finish将RightGrid集合发送到数据库
如果这是一个很好的例子,那会有帮助的。例如,我需要假设您的
ICollection
s是observedcollection
s。既然不是,那就意味着我不能重复你的问题,只能猜测了
错误表明WPF正在努力跟上对可观察集合所做的更改。这通常不会发生
在给定的AddItem relay命令中,它迭代AllItems集合。在迭代的中间,它从集合中移除一个项,尽管它在紧接着之后就超出了FACACH。使用Linq的第一种方法可以避免这种方法:
private void AddItem(int itemId)
{
var allItem = AllItems.First(i=>i.Id == itemId);
AllItems.Remove(allItem);
AddedItems.Add(allItem);
}
但实际上,你可以更进一步,让自己的生活更轻松。在XAML中,将CommandParameter=“{Binding Id}”
更改为CommandParameter=“{Binding}”
,并将AddItem的参数更改为RentalItem
而不是int
(同时更改RelayCommand的声明)。这样,您就不需要找到该项,因为它是作为参数传递的
我希望这样做将意味着可以及时处理对集合的更改。我的问题已经解决:我像这样声明了我的列表AddedItems=new list();但它实际上应该是一个可以观察到的集合,就像你想象的那样。谢谢你,那真的很有用。
public class NewRentalViewModel : ViewModelBase, IViewModel
{
private ItemService itemService;
private UserService userService;
private RentalItemService rentalItemService;
private ICollection<RentalItem> allItems;
private ICollection<RentalItem> addedItems;
private User user;
public RelayCommand CloseCommand { get; private set; }
public RelayCommand<int> AddItemCommand { get; private set; }
public RelayCommand<int> RemoveItemCommand { get; private set; }
public ICollection<RentalItem> AllItems
{
get { return allItems; }
set
{
allItems = value;
RaisePropertyChanged();
}
}
public ICollection<RentalItem> AddedItems
{
get { return addedItems; }
set
{
addedItems = value;
RaisePropertyChanged();
}
}
public User User
{
get { return user; }
set
{
user = value;
RaisePropertyChanged();
}
}
public NewRentalViewModel(int userId)
{
userService = new UserService();
itemService = new ItemService();
User = userService.Get(userId);
rentalItemService = new RentalItemService();
InstantiateCommands();
LoadItems();
}
private void InstantiateCommands()
{
CloseCommand = new RelayCommand(Close);
AddItemCommand = new RelayCommand<int>(AddItem);
RemoveItemCommand = new RelayCommand<int>(RemoveItem);
}
private void LoadItems()
{
AllItems = rentalItemService.GetAvailableRentalItems(new RentalItemIncludes(){Item = true});
AddedItems = new List<RentalItem>();
}
private void Close()
{
var viewModel = new NavigationViewModel();
var message = new NavigationMessage { ViewModel = viewModel };
Messenger.Default.Send(message);
}
private void AddItem(int itemId)
{
foreach (var allItem in AllItems)
{
if (allItem.Id == itemId)
{
AllItems.Remove(allItem);
AddedItems.Add(allItem);
break;
}
}
}
private void RemoveItem(int itemId)
{
}
}
public partial class NewRentalView : UserControl
{
public NewRentalView()
{
InitializeComponent();
}
private void OnAddButton(object sender, RoutedEventArgs e)
{
//Item item = (Item)((Button)sender).Tag;
//AllItemsGrid.Items.RemoveAt(item.Id);
AllItemsGrid.Items.Refresh();
AddedItemsGrid.Items.Refresh();
}
}
private void AddItem(int itemId)
{
var allItem = AllItems.First(i=>i.Id == itemId);
AllItems.Remove(allItem);
AddedItems.Add(allItem);
}