0

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?

  1. 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.

  1. Refreshing the Accordian after doing the above change again gave the exception.
  2. Making the ItemsSource null and then assigning again also gave the exception

The answers already posted doesn't solve my problem

Community
  • 1
  • 1
sandy93
  • 59
  • 1
  • 6
  • Please provide real code, this shouldn't compile. – H H Sep 10 '15 at 10:49
  • Sorry. I am posting for the first time. Please let me know if i should add something else – sandy93 Sep 10 '15 at 11:05
  • You should post the stack trace of the exception. – dymanoid Sep 10 '15 at 11:14
  • I see you're having some problems formatting your code. Just a tip. Start a new C# file(or whatever language you're working in) in your IDE and paste your code in that file. Let the IDE format your code and then when you put it in your post you can format it with the StackOverflow indent function. – Martijn Sep 10 '15 at 11:40
  • And about the code, you're removing the obj in the method RemoveAddedCity AFTER the foreach. The variable named obj can't be known in that scope. So as Henk Holterman said, provide real code so we can help you identify the problem. – Martijn Sep 10 '15 at 11:42
  • Sorry didn't see that. Changed it now. Still getting the same exception – sandy93 Sep 10 '15 at 12:20
  • 1
    @sandy93 I have no experience with the Accordion Control but looking at the StackTrace it seems to be a problem with the selection. Is there maybe an IsSelected property on the item you want to remove that you first need to set to false? – Martijn Sep 10 '15 at 14:23
  • 2
    If after following all of the advice in the duplicate question you are still unable to solve your problem, please post [a good, _minimal_, _complete_ code example](https://stackoverflow.com/help/mcve) that reliably reproduces the problem. It is clear from the stack trace that an anonymous method in the method `System.Windows.Controls.AccordionItem.StartAction()` is throwing the exception, but this may be a bug in your code (incorrectly configuring the control) or a bug in the control itself. You need to do some investigation yourself. – Peter Duniho Sep 10 '15 at 19:23
  • @MartijnvandenH I am not deleting the selected item. I checked the `SelectedIndex` property. The expanded item cannot be deleted as the button click is not enabled in the selected header. That is another issue. Right now I am trying to delete items that are not expanded i.e not selected – sandy93 Sep 11 '15 at 06:32

0 Answers0