我看到很多与此问题相关的帖子,但我找不到解决方案
我有下一个 WPF DataGrid:
<DataGrid Grid.Column="1"
Grid.Row="4"
AutoGenerateColumns="False"
ItemsSource="{Binding MapsGrid}"
SelectedItem="{Binding DataContext.CategoriesSelectedRow, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWayToSource}"
SelectionMode="Single"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserDeleteRows="False"
CanUserResizeRows="False"
CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Main Category"
Width="*">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="FontSize"
Value="16" />
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding MainCategoriesColl}"
DisplayMemberPath="Category"
SelectedItem="{Binding MainCategorySelectedItem,UpdateSourceTrigger=LostFocus, Mode=OneWayToSource}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Sub Category"
Width="*">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="FontSize"
Value="16" />
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding SubCategoriesColl}"
DisplayMemberPath="Category"
SelectedItem="{Binding SubCategorySelectedItem, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
此 DataGrid 包含 2 个组合框。ItemSource 对象是下一个对象:
public class MapsDescModel : NotificationObject, IEqualityComparer<MapsDescModel>, IEquatable<MapsDescModel>
{
public MapsDescModel(ObservableCollection<MainCategories> mainCategoty)
{
MainCategoriesColl = mainCategoty;
}
public static event Action OnSelectionHandler;
private static void OnSelection()
{
if (OnSelectionHandler != null)
{
OnSelectionHandler();
}
}
private MainCategories _mainCategorySelectedItem;
public MainCategories MainCategorySelectedItem
{
get { return _mainCategorySelectedItem; }
set
{
if (Equals(value, _mainCategorySelectedItem)) return;
_mainCategorySelectedItem = value;
RaisePropertyChanged("MainCategorySelectedItem");
RaisePropertyChanged("SubCategoriesColl");
}
}
private SubCategories _subCategorySelectedItem;
public SubCategories SubCategorySelectedItem
{
get { return _subCategorySelectedItem; }
set
{
if (Equals(value, _subCategorySelectedItem)) return;
_subCategorySelectedItem = value;
RaisePropertyChanged("SubCategorySelectedItem");
OnSelection();
}
}
private ObservableCollection<MainCategories> _mainCategoriesColl;
public ObservableCollection<MainCategories> MainCategoriesColl
{
get { return _mainCategoriesColl; }
set
{
if (Equals(value, _mainCategoriesColl)) return;
_mainCategoriesColl = value;
RaisePropertyChanged("MainCategoriesColl");
}
}
//Allow user see N/A category just if is the only subCategory that exists
public ObservableCollection<SubCategories> SubCategoriesColl
{
get
{
if (MainCategorySelectedItem != null && MainCategorySelectedItem.SubCategory.Any())
if (MainCategorySelectedItem.SubCategory.Count() > 1)
{
return Infrastructure.Helpers.ExtensionMethods.ToObservableCollection(
MainCategorySelectedItem.SubCategory.AsEnumerable().Where(p => p.Category != Infrastructure.Constants.Constants.NoSubCategory));
}
else return Infrastructure.Helpers.ExtensionMethods.ToObservableCollection(
MainCategorySelectedItem.SubCategory.AsEnumerable());
else return new ObservableCollection<SubCategories>();
}
}
public bool Equals(MapsDescModel x, MapsDescModel y)
{
try
{
if (x.MainCategorySelectedItem == null && y.MainCategorySelectedItem == null)
return true;
else if (x.MainCategorySelectedItem == null && y.MainCategorySelectedItem != null ||
x.MainCategorySelectedItem != null && y.MainCategorySelectedItem == null)
return false;
return
x.MainCategorySelectedItem.MainCatID == y.MainCategorySelectedItem.MainCatID &&
x.SubCategorySelectedItem.SubCatID == y.SubCategorySelectedItem.SubCatID;
}
catch (Exception ex)
{
ServiceLocator.Current.GetInstance<Infrastructure.SharedServices.IEnterpriseLibraryLogger>().Log(ex.Message, Category.Exception, Priority.High);
return false;
}
}
public int GetHashCode(MapsDescModel obj)
{
if (Object.ReferenceEquals(obj, null)) return 0;
if (obj.MainCategorySelectedItem == null || obj.SubCategorySelectedItem == null)
return 0;
else return obj.SubCategorySelectedItem.Category.GetHashCode() + obj.MainCategorySelectedItem.GetHashCode();
}
public bool Equals(MapsDescModel other)
{
return
this.Equals(this, other); // use definition from IEqualityComparer<T>
}
public override bool Equals(object obj)
{
MapsDescModel other = obj as MapsDescModel;
if (other == null)
return base.Equals(obj);
else
return this.Equals(other);
}
public override int GetHashCode()
{
MapsDescModel other = this as MapsDescModel;
if (other == null)
return base.GetHashCode();
else
return this.GetHashCode(other);
}
}
除了一个烦人的问题外,一切都很好。当我添加 2+ 行时,如果我在附图中的标记区域上单击几次,我会收到以下错误:
System.ArgumentException was unhandled
HResult=-2147024809
Message=An item with the same key has already been added.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2..ctor(IDictionary`2 dictionary, IEqualityComparer`1 comparer)
at System.Windows.Controls.Primitives.Selector.InternalSelectedItemsStorage..ctor(InternalSelectedItemsStorage collection, IEqualityComparer`1 equalityComparer)
at System.Windows.Controls.Primitives.Selector.SelectionChanger.ApplyCanSelectMultiple()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
at System.Windows.Controls.SelectedItemCollection.EndUpdateSelectedItems()
at System.Windows.Controls.Primitives.MultiSelector.EndUpdateSelectedItems()
at System.Windows.Controls.DataGrid.MakeFullRowSelection(ItemInfo info, Boolean allowsExtendSelect, Boolean allowsMinimalSelect)
at System.Windows.Controls.DataGrid.HandleSelectionForRowHeaderAndDetailsInput(DataGridRow row, Boolean startDragging)
at System.Windows.Controls.Primitives.DataGridRowHeader.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonDown(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at Malaria.App.Main() in c:\My Projects\Hebrew University\Malaria Management Console\Malaria\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
我认为这可能与我的GetHashCode
方法有关,但我不确定。我找到了这个链接
http://leavinsprogramming.blogspot.co.il/2012/08/wpf-datagrid-and-random.html
它很好地描述了我的问题,但那里没有解决方案。有谁知道为什么会发生这种异常?