I am using the wpfToolkit Accordian control
and I have bound it to an observable collection. When I remove an item from the collection,the removal happens but immediately it throws Null Reference Exception at the end of the function. Looks like something to do with Binding.
StackTrace:
at System.Windows.Controls.AccordionItem.<StartAction>b__1()
at System.Windows.Controls.AccordionItem.StartAction()
at System.Windows.Controls.AccordionItem.Schedule(AccordionAction action)
at System.Windows.Controls.AccordionItem.ToggleSelected(RoutedEventArgs args)
at System.Windows.Controls.AccordionItem.OnSelected()
at System.Windows.Controls.AccordionItem.OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.AccordionItem.set_IsSelected(Boolean value)
at System.Windows.Controls.AccordionItem.OnExpanderButtonClicked(Object sender, RoutedEventArgs e)
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.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(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.OnMouseUpThunk(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 WeatherApp.Startup.Main() in c:\Users\skannan\Documents\Visual Studio 2013\Projects\WeatherApp\WeatherApp\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()
Code:
<layout:Accordion Name="AccordianControl" ItemsSource="{Binding WeatherDataCollection}" Grid.Row="2" Visibility="Hidden" FontWeight="Bold" HorizontalAlignment="Stretch" Background="Transparent"
>
<layout:Accordion.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent" Width="{Binding ActualWidth,ElementName=MainGrid}"
Height="{Binding Binding ActualWidth,ElementName=MainGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Button Name="IndividualMinusButton" Tag="{Binding City}" Width="40" Height="40" Click="IndividualMinusButton_Click" HorizontalAlignment="Right" Template="{StaticResource MinusButtonTemplate}" Background="Red"
Visibility="Hidden" Grid.Column="0"/>
<TextBlock Text="{Binding City}" HorizontalAlignment="Left" Grid.Column="0" Margin="10,10,10,10"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Right" Text="Max:" Margin="10,10,10,10" />
<TextBlock HorizontalAlignment="Right" Text="{Binding MaxTemp}" Margin="10,10,10,10"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Right" Text="Min:" Margin="10,10,10,10" />
<TextBlock HorizontalAlignment="Right" Text="{Binding MinTemp}" Margin="10,10,10,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</layout:Accordion.ItemTemplate>
<layout:Accordion.ContentTemplate>
<DataTemplate>
<StackPanel Height="auto" Width="auto" Orientation="Horizontal" Background="Transparent">
<Image Source="{Binding WeatherIcon}" Margin="10,10,10,10" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="Humidity:" Margin="10,10,10,10" Foreground="SandyBrown" />
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding Humidity}" Margin="10,10,10,10" Foreground="SandyBrown" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="MinimumTemperature:" Margin="10,10,10,10" Foreground="SandyBrown" />
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding MinTemp}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="MaximumTemperature:" Margin="10,10,10,10" Foreground="SandyBrown"/>
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding MaxTemp}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="WindSpeed:" Margin="10,10,10,10" Foreground="SandyBrown"/>
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding WindSpeed}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="Sunrise:" Margin="10,10,10,10" Foreground="SandyBrown"/>
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding Sunrise}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="Sunset:" Margin="10,10,10,10" Foreground="SandyBrown"/>
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding Sunset}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="Description:" Margin="10,10,10,10" Foreground="SandyBrown"/>
<TextBlock HorizontalAlignment="Left" FontFamily="Arial" FontSize="14" Text="{Binding WeatherDesc}" Margin="10,10,10,10" Foreground="SandyBrown"/>
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
</layout:Accordion.ContentTemplate>
</layout:Accordion>
WeatherData.cs
public class WeatherData
{
public string City { get; set; }
public string Humidity { get; set; }
public string MaxTemp { get; set; }
public string MinTemp { get; set; }
public string Sunset { get; set; }
public string Sunrise { get; set; }
public BitmapImage WeatherIcon { get; set; }
public string WeatherDesc { get; set; }
public string WindSpeed { get; set; }
public WeatherData()
{
}
public WeatherData(string city,string humid,string maxt,string mint,string srise,string sset,string wspeed, BitmapImage icon,string desc)
{
City = city;
Humidity = humid;
MaxTemp = maxt;
MinTemp = mint;
Sunrise = srise;
Sunset = sset;
WindSpeed = wspeed;
WeatherIcon = icon;
WeatherDesc = desc;
}
public override string ToString()
{
return string.Format("Humidity:{0} \nMaximumTemperature:{1} \nMinimumTemperature:{2} \nSunrise:{3} \nSunset:{4} \nWindspeed:{5} \nWeatherIcon:{6} \nCityName:{7}",Humidity,MaxTemp,MinTemp,Sunrise,Sunset,WindSpeed,WeatherIcon,City);
}
}
CodeBehind:
public ObservableCollection<WeatherData> WeatherDataCollection
{
get { return _weatherDataCollection; }
set { _weatherDataCollection = value; NotifyPropertyChanged("WeatherDataCollection"); }
}
void WeatherDataCollection1_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("WeatherDataCollection");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
private void IndividualMinusButton_Click(object sender, RoutedEventArgs e)
{
string citytoremove = (sender as Button).Tag.ToString();
if(!string.IsNullOrEmpty(citytoremove))
{
RemoveAddedCity(citytoremove);
}
}
public void RemoveAddedCity(string city)
{
int index = -1;
foreach (WeatherData obj in WeatherDataCollection)
{
if (obj != null)
{
if (string.Equals(obj.City, city, StringComparison.CurrentCultureIgnoreCase))
{
index = WeatherDataCollection.IndexOf(obj);
break;
}
}
}
if(index>=0)
{
WeatherDataCollection.RemoveAt(index);
}
WeatherApp.Properties.Settings.Default.SavedCities.Remove(city);
Properties.Settings.Default.Save();
}
Things Tried:
Referring to the other stackoverflow links, i tried: [WPF ObservableCollection.Remove throws NullReferenceException [Why does ObservableCollection throws an exception when being modified?
- Making the object null before removing.i.e
obj = null; WeatherDataCollection.Remove(obj);
Consequence: CollectionChanged is not called, so Accordian is not updated but the exception disappeared.
- Refreshing the Accordian after doing the above change again gave the exception.
- Making the
ItemsSource
null and then assigning again also gave the exception
The answers already posted doesn't solve my problem
- [1]: WPF ObservableCollection.Remove throws NullReferenceException
[2]: Why does ObservableCollection throws an exception when being modified?
Please help me identify the problem and resolve it. Thanks in advance