Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8300507
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T16:35:08+00:00 2026-06-08T16:35:08+00:00

I have a View with a DataGrid in it. A ViewModel as DataContext where

  • 0

I have a View with a DataGrid in it.
A ViewModel as DataContext where i can access a DataTable in a background object.
The background object has to work with the DataTable and keep it updated.
The user has also be allowed to make changes to that DataTable.

If i create a copy of the DataTable it stops crashing but the user is obviousely not working on the data.

If i leave access open for the user the program crashed inevitabely.

Here is a short program that will crash:

app.cs

public partial class App : Application
{
    public App()
    {
        SomeBackgroundThing background = new SomeBackgroundThing();
        MainWindowViewModel viewmodel = new MainWindowViewModel(background);
        MainWindowView view = new MainWindowView(viewmodel);
        view.Show();
    }
}

main xaml

<Window x:Class="NullPointerDataGrid.MainWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="datagrid" ItemsSource="{Binding Path=table, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
    </Grid>
</Window>

and the program code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Data;
using System.Diagnostics;
using System.Timers;
using System.ComponentModel;

namespace NullPointerDataGrid
{
    public partial class MainWindowView : Window
    {
        public MainWindowView(MainWindowViewModel model)
        {
            DataContext = model;
            InitializeComponent();
            datagrid.Loaded += new RoutedEventHandler(ScrollToBottom);
            datagrid.AutoGeneratedColumns += new EventHandler(StarSizeLastRow);

        }

    void ScrollToBottom(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("TableGrid_ScrollToBottom");
        if (datagrid.Items.Count > 0)
        {
            var border = VisualTreeHelper.GetChild(datagrid, 0) as Decorator;
            if (border != null)
            {
                var scroll = border.Child as ScrollViewer;
                if (scroll != null) scroll.ScrollToEnd();
            }
        }

    }

    void StarSizeLastRow(object sender, EventArgs e)
    {
        Debug.WriteLine("TableGrid_StarSizeLastColumn");
        try
        {
            datagrid.Columns[datagrid.Columns.Count - 1].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
        }
        catch { }
    }

    }

public class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private SomeBackgroundThing thing;
    public DataTable table
    {
        get
        {
            lock (thing.table)
            {
                //DataTable wpfcopy = thing.table.Copy();
                return thing.table;
            };
        }
        set
        {
            Debug.Write("This never happens");
        }
    }

    public MainWindowViewModel(SomeBackgroundThing thing)
    {
        this.thing = thing;
        thing.Changed += new EventHandler(thing_Changed);
    }

    void thing_Changed(object sender, EventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("table"));
        }
    }
}

public class SomeBackgroundThing : IDisposable
{
    public DataTable table;
    private DataTable tablecopy;
    private System.Timers.Timer timer, slowrowchanger;

    public event EventHandler Changed = new EventHandler((o, e) => { ;});
    protected void CallChanged(object sender, EventArgs e)
    {
        Changed(sender, e);
    }

    public SomeBackgroundThing()
    {
        CreateTable();
        UpdateB(this, null);
        tablecopy = table.Copy();
        InitAndStartTimer(1);
    }

    #region timer

    private void UpdateA()
    {
        Boolean haschanged = false;
        DataTable newcopy = table.Copy(); ;
        if (newcopy.Rows.Count != tablecopy.Rows.Count)
        {
            Debug.WriteLine("Different ammount of rows");
            haschanged = true;
        }
        else if (newcopy.Columns.Count != tablecopy.Columns.Count)
        {
            Debug.WriteLine("Different ammount of columns");
            haschanged = true;
        }
        else
        {
            for (int i = 0; i < newcopy.Rows.Count; i++)
            {
                for (int j = 0; j < newcopy.Columns.Count; j++)
                {
                    if (newcopy.Rows[i][j].ToString() != tablecopy.Rows[i][j].ToString())
                    {
                        Debug.WriteLine(String.Format(
                            "Element [{0}/{1}]: {2} is different from {3}",
                            i, j, newcopy.Rows[i][j], tablecopy.Rows[i][j]
                            ));
                        haschanged = true;
                    }
                    if (haschanged) break;
                }
                if (haschanged) break;
            }
        }
        if (haschanged)
        {
            tablecopy = newcopy;
        }
    }

    private void InitAndStartTimer(int interval)
    {
        timer = new System.Timers.Timer();
        timer.Interval = interval;
        timer.AutoReset = true;
        timer.Elapsed += new ElapsedEventHandler((s, e) =>
        {
            UpdateA();
        });
        timer.Enabled = true;

        slowrowchanger = new System.Timers.Timer();
        slowrowchanger.Interval = 3000;
        slowrowchanger.AutoReset = true;
        slowrowchanger.Elapsed += new ElapsedEventHandler((s, e) =>
        {
            UpdateB(null, null);
        });
        slowrowchanger.Enabled = true;

    }

    public void Dispose()
    {
        timer.Enabled = false;
        slowrowchanger.Enabled = false;
        timer.Dispose();
        slowrowchanger.Dispose();
    }

    #endregion

    #region editlastrow

    void UpdateB(object sender, EventArgs e)
    {
        Random rnd = new Random();
        List<String> cells = new List<string>{
                "The SAME", 
                rnd.Next(0,100).ToString(), 
                rnd.ToString(), 
                rnd.NextDouble().ToString()};
        lock (table)
        {
            OverwriteOrAppendLastRow(ref table, cells);
            table.AcceptChanges();
        }
        CallChanged(this, null);
    }

    private void OverwriteOrAppendLastRow(ref DataTable table, List<string> newrow)
    {
        if (table.Rows.Count == 0) CreteEmptyRow(ref table);
        if (newrow[0].ToString() != table.Rows[table.Rows.Count - 1][0].ToString())
        {
            Debug.WriteLine(String.Format("Creating row because '{0}' is different from '{1}'", newrow[0], table.Rows[table.Rows.Count - 1][0]));
            CreteEmptyRow(ref table);
        }
        OverwriteLastRow(ref table, newrow);
    }

    private void OverwriteLastRow(ref DataTable table, List<string> newrow)
    {
        for (int i = 0; i < newrow.Count() && i < table.Columns.Count; i++)
        {
            table.Rows[table.Rows.Count - 1][i] = newrow[i];
        }
    }

    private void CreteEmptyRow(ref DataTable table)
    {
        table.Rows.Add(new String[table.Columns.Count]);
    }

    #endregion

    private void CreateTable()
    {
        table = new DataTable();
        table.Columns.Add("FirstCell", typeof(String));
        table.Columns.Add("BananaCell", typeof(String));
        table.Columns.Add("CherryCell", typeof(String));
        table.Columns.Add("Blue", typeof(String));
        Random rnd = new Random();
        for (int i = 0; i < 145; i++)
        {
            table.Rows.Add(new String[]{
                rnd.Next().ToString(), 
                rnd.Next(0,i+1).ToString(), 
                rnd.ToString(), 
                rnd.NextDouble().ToString()});
        }
    }

}

}

How can i stop this multithread crashing?


EDIT:

I don’t know if there are more than one reasons for this code to crash. But i did my best to gather some information about one reason to crash:

Nullpointer exception in App.g.cs – the autogenerated portion. The Debugger wont step into it – so i cant say anything about the line it crashes in.

Here is the Exception Detail, sorry for the German.

System.NullReferenceException wurde nicht behandelt.
  Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
  Source=PresentationFramework
  InnerException: 

The Stacktrace only shows “Externer Code” so no stack to trace.

The thing is that WPF crashes – my code can handle it… somehow i need to capsule WPF so it wont crash, one way to do that is to copy the DataTable – but then i loose the ability to write back that table since its setter is not called when something has gotten edited.

EDIT #2:

I recreated this example to show the error i have in another program and i just found out that what crashes is actually related with the scrollbar. If i change the ammount of displayed data to a low number so that there is no scrollbar, the code will not crash.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T16:35:12+00:00Added an answer on June 8, 2026 at 4:35 pm

    The following change to the viewmodel solves the problem.

    I am now using a copy for wpf to work on and only note the canges should they occur. This code has an issue with the poorly refined change mechanism – but that is beyond the scope of this question.

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private SomeBackgroundThing thing;
    
        private DataTable wpftable;
        public DataTable table
        {
            get
            {
                lock (wpftable)
                {
                    return wpftable;
                }
    
            }
    
            set
            {
                lock (wpftable)
                {
                    wpftable = value;
                }
            }
        }
    
        public MainWindowViewModel(SomeBackgroundThing thing)
        {
            wpftable = thing.table.Copy();
            this.thing = thing;
            thing.Changed += new EventHandler(thing_Changed);
        }
    
        void thing_Changed(object sender, EventArgs e)
        {
            if (PropertyChanged != null)
            {
                DataTable wpftablecopy = wpftable.Copy();
                DataTable thintablecopy = thing.table.Copy();
                int rowcount = wpftablecopy.Rows.Count;
                for (int col = 0; col < 4; col++)
                {
                    for (int row = 0; row < rowcount; row++)
                    {
                        if (wpftablecopy.Rows[row][col] != thintablecopy.Rows[row][col])
                            wpftable.Rows[row][col] = thintablecopy.Rows[row][col];
                    }
                }
                PropertyChanged(this, new PropertyChangedEventArgs("table"));
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i have view like 'home/details/5', it can be access by anonymous user. but there
I have a datagrid within a view <Grid x:Name=LayoutRoot Background=White Width=600 MaxHeight=150> <sdk:DataGrid x:Name=grid1
I have a view with a dataGrid and the ViewModel. I want that when
I have a datagrid view which is editable. I'm getting the value of a
I'm having problem with datagrid view. I have attached an image with the code
Hi I have a mainView window which has its dataContext set to it's own
Using MVVM and EF...I have a datagrid binding to a View Model (using ObservableCollection).
I have a View that displays a DataGrid which is bound to an ObservableCollection
I have a TabControl where each tab contains a DataGrid . When the user
I have a datagrid bound to a CollectionViewSource view in my view model. The

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.