So in my application i have a need to display some images For that i used ItemsControl
and UniformGrid
data bound to ObservableCollection<Image>
like this
<ItemsControl Name="ImageItemsControl" ItemsSource="{Binding Path=ObservableCollectionSource}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
It works just fine, when i just start the program, But then at some point, i need to unload all the images from the grid. Because if i call .Clear()
on my collection it breaks my binding, just remove all the elements one by one like this:
int limit = ObservableCollectionSource.Count -1;
for (int i = limit; i >= 0; i--)
{
ObservableCollectionSource.RemoveAt(i);
}
At first glance it seems to work correctly, but then when i need to add images back to the grid(by drag and drop, or from open file dialog - result is the same). It throws this exception
specified argument was out of the range of valid values. parameter name index
At the line where i call .Add()
method.
Image img = CreateImage(cImg);
try
{
ObservableCollectionSource.Add(img);
}
catch (Exception ex )
{
MessageBox.Show("Exception has occured: " + ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
}
Here i create wpf image with necessary "settings" from the bitmap that I loaded from file, And try to add it to my ObservableCollection.
Any ideas why it doesn't work, or directions for me to do research about?
Googling around didn't produce any results(maybe i just formulated my search queries poorly), and i'm all out of ideas.
Do I bind it wrong? Do I use wrong controls for the task?
I don't know.
Any help is greatly appreciated
EDIT: Here is Stack Trace from the Exception that i get
at System.Windows.Media.VisualCollection.Insert(Int32 index, Visual visual)
at System.Windows.Controls.Panel.AddChildren(GeneratorPosition pos, Int32 itemCount)
at System.Windows.Controls.Panel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index)
at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Controls.ItemCollection.OnViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at MainDesk.MainWindow.AddImagesToGrid() in D:\MainDesk\MainDesk\UI\MainWindow.xaml.cs:line 427
at MainDesk.MainWindow.AddCarrierImageBtn_Click(Object sender, RoutedEventArgs e) in D:\MainDesk\MainDesk\UI\MainWindow.xaml.cs:line 167
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.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(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.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(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 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, 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.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at MainDesk.App.Main() in D:\MainDesk\MainDesk\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()
So it seems I figured out where my mistake was.
First of all. About .Clear()
breaking my binding. - I completely forgot about NotifyPropertyChanged
. However, when i got this part figured out, the exception persisted.
Now to the main part - I overestimated, the simplicity of my application, and as a result didn't post enough relevant info. After i was unable to reproduce the problem in a smaller app, that had nothing in it but one ObservableCollection
and one ItemsPanel
with UniformGrid
in it. I knew the problem is somewhere else.
So it turns out, that i for some reason, at the same time i was adding the Image
s to the ObservableCollection
in question, i was also adding this images to another ObservableCollection
which was ItemsSource
for another ItemsPanel
. Two panels are identical, but have no knowledge of each other, and are not connected in any way.
Thing is, one of them was had it's Visibility
as Visibility.Collapsed
when i was adding items to it's ObservableCollection
.
Now, when i only work with one ObservalbeCollection
at a time - problem is gone.
Though i still have no idea what was the cause of such behavior.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.