0
votes

When I make a call to FillGPLocationAndPrint in the DataGridViewModel class, I get this exception. Below is the inner exception. What happens is a hard coded Dictionary is passed into FillGPLocationAndPrint where it takes the data from there and puts it into the GridData ObservableCollection which is bound to the ItemsSource property of the DataGrid. This raises an event called CollectionChanged, which calls the method GridDataChanged which is responsible for increasing the DataGrid height property and the MainWindow height property. Basically, as rows are added and subtracted, the grid and window height change dynamically.

Edit:

After looking a little further into this issue, the problem is actually caused by the

mainVm.WindowHeight += ROW_HEIGHT;

and

mainVm.WindowHeight -= ROW_HEIGHT;

statements. For some reason, it does not like changing the height of the window. mainVm is an object that represents the ViewModel of the main window and WindowHeight is a double that is bound to the Height property in the main window.

Here is InnerException:

Information for developers (use Text Visualizer to read this): This exception was thrown because the generator for control 'System.Windows.Controls.DataGrid Items.Count:3' with name 'grdData' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection. The following differences were detected: Accumulated count 2 is different from actual count 3. [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).] At index 1: Generator's item '{NewItemPlaceholder}' is different from actual item 'MechQualTestDataEntry.MechTestData'.

One or more of the following sources may have raised the wrong events: System.Windows.Controls.ItemContainerGenerator System.Windows.Controls.ItemCollection System.Windows.Data.ListCollectionView System.Collections.ObjectModel.ObservableCollection`1[[MechQualTestDataEntry.MechTestData, MechQualTestDataEntry, Version=2.0.5.25, Culture=neutral, PublicKeyToken=null]] (The starred sources are considered more likely to be the cause of the problem.)

The most common causes are (a) changing the collection or its Count without raising a corresponding event, and (b) raising an event with an incorrect index or item parameter.

The exception's stack trace describes how the inconsistencies were detected, not how they occurred. To get a more timely exception, set the attached property 'PresentationTraceSources.TraceLevel' on the generator to value 'High' and rerun the scenario. One way to do this is to run a command similar to the following: System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High) from the Immediate window. This causes the detection logic to run after every CollectionChanged event, so it will slow down the application.

Here is the DataGridViewModel class (shrunk down):

    private const int GRID_HEIGHT_MAX = 390;
    private const int GRID_HEIGHT_MIN = 60;
    private const int ROW_HEIGHT = 22;
    private int prevRowCount;
    private double gridHeight;
    private MainWindowViewModel mainVm;
    private ObservableCollection<MechTestData> gridData;
    public DataGridViewModel(MainWindowViewModel mainVm)
    {
        this.mainVm = mainVm;
        GridHeight = GRID_HEIGHT_MIN;
        gridData = new ObservableCollection<MechTestData>();
        gridData.CollectionChanged += GridDataChanged;
    }
    public double GridHeight
    {
        get
        {
            return gridHeight;
        }
        set
        {
            gridHeight = value;
            OnPropertyChanged("GridHeight");
        }
    }
    public ObservableCollection<MechTestData> GridData
    {
        get
        {
            return gridData;
        }
        set
        {
            gridData = value;
            OnPropertyChanged("GridData");
        }
    }
    private void GridDataChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // If the grid height is less than or equal to
        // the maximum grid height
        if (gridHeight <= GRID_HEIGHT_MAX + 1)
        {
            // If we added rows, increase the grid height
            if (gridData.Count > prevRowCount)
            {
                GridHeight += ROW_HEIGHT;
                mainVm.WindowHeight += ROW_HEIGHT;
            }
        }

        // if the grid height is less than or equal to
        // the minimum grid height
        if (gridHeight > GRID_HEIGHT_MIN)
        {
            // If we deleted rows, decrease the grid height
            if (gridData.Count < prevRowCount)
            {
                GridHeight -= ROW_HEIGHT;
                mainVm.WindowHeight -= ROW_HEIGHT;
            }
        }

        // Cache the row count
        prevRowCount = gridData.Count;
    }
    public void FillGPLocationAndPrint(Dictionary<string, string> gpLocationToDiePrintMap)
    {
        foreach (KeyValuePair<string, string> map in gpLocationToDiePrintMap)
        {
            GridData.Add(new MechTestData(map.Key, map.Value));
        }
    }

ViewModelBase class:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAML (minus all the other components):

<Window 
x:Class="MechQualTestDataEntry.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:MechQualTestDataEntry.Properties"
xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:local="clr-namespace:MechQualTestDataEntry"
Icon="/MechQualTestDataEntry;component/Resources/MechQualIcon.ico"
Title="MainWindow" 
Background="MidnightBlue"
ResizeMode="CanMinimize"
Height="{Binding WindowHeight}"
MinHeight="{Binding WindowHeight}"
MaxHeight="{Binding WindowHeight}"
MinWidth="700"
MaxWidth="1000"
Width="820">
<Window.Resources>
    <local:DateTimeConverter x:Key="DateTimeFormatter"/>
</Window.Resources>

    <!-- Data Grid -->
    <DataGrid
        DockPanel.Dock="Bottom"
        x:Name="grdData"
        CellStyle="{StaticResource cellStyle}"
        FontFamily="Verdana"
        Height="{Binding GridHeight}"
        Foreground="MidnightBlue"
        AutoGenerateColumns="False"
        RowHeight="22"
        CanUserAddRows="True"
        CanUserDeleteRows="True"
        CanUserReorderColumns="False"
        CanUserResizeColumns="False"
        CanUserResizeRows="False"
        CanUserSortColumns="True"
        ItemsSource="{Binding GridData}"
        SelectionUnit="CellOrRowHeader"
        SelectionMode="Extended">
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridCell}">
                <EventSetter 
                    Event="PreviewMouseLeftButtonDown" 
                    Handler="DataGridCell_PreviewMouseLeftButtonDown"/>
            </Style>
            <Style TargetType="{x:Type DataGridRowHeader}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="Background" Value="DeepSkyBlue" />
                        <Setter Property="BorderBrush" Value="MidnightBlue" />
                        <Setter Property="BorderThickness" Value="1" />
                        <Setter Property="Width" Value="15" />
                        <Setter Property="HorizontalContentAlignment" Value="Right" />
                        <Setter Property="VerticalContentAlignment" Value="Center" />
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="MidnightBlue" />
                        <Setter Property="BorderBrush" Value="DeepSkyBlue" />
                        <Setter Property="BorderThickness" Value="1" />
                        <Setter Property="Width" Value="15" />
                        <Setter Property="HorizontalContentAlignment" Value="Right" />
                        <Setter Property="VerticalContentAlignment" Value="Center" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>

            <!-- TO Number -->
            <DataGridTextColumn 
                Width="40"
                Binding="{Binding TONumber}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="TO #"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- GelPak Location -->
            <DataGridTextColumn 
                Width="60"
                Binding="{Binding GelPakLocation}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="GelPak Location"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Die Print -->
            <DataGridTextColumn 
                Width="60"
                Binding="{Binding DiePrint}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            Text="Die Print"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Wire Pull Test -->
            <DataGridTextColumn 
                Width="70"
                Binding="{Binding WirePullTestValue}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="Wire Pull Test"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Failure Mode -->
            <DataGridTextColumn 
                Width="84"
                Binding="{Binding FailureMode}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            Text="Failure Mode"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Ball Shear -->
            <DataGridTextColumn 
                Width="70"
                Binding="{Binding BallShearTestValue}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="Ball Shear Test"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Die Shear -->
            <DataGridTextColumn 
                Width="70"
                Binding="{Binding DieShearTestValue}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="Die Shear Test"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- InP Remaining -->
            <DataGridTextColumn 
                Width="70"
                Binding="{Binding InPRemaining}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="InP Remaining"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Test Result -->
            <DataGridTextColumn 
                Width="70"
                Binding="{Binding TestResult}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="Pass/Fail"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <!-- Notes -->
            <DataGridTextColumn
                Width="*"
                Binding="{Binding Notes}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock
                            Style="{StaticResource tbkStyleGridHeader}"
                            TextWrapping="Wrap"
                            Text="Notes"/>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

Any help in solving this problem will much appreciated.

Regards,

Kyle

2
possible quick solution off the top of my head: put the offending code in a Dispatcher.BeginInvoke(). - Federico Berasategui
Just tried this and it throws the exact same exception. I put: GridData.Add(new MechTestData(map.Key, map.Value)); inside the dispatcher invoke method. - kformeck
I want to also add that my original solution works perfectly on my development machine, but when I deploy it, I get this exception on almost every production machine. All production machines are running the same OS as my dev machine: Windows 7 Professional x64 with .NET 4.0 installed - kformeck

2 Answers

1
votes

My issue resolved by this method. Go to visual studio > Tool >Option > Debugging > Databinding> Vorbose.

-2
votes

I figured I would answer this question since it's been a while since I posted this. The issue was a .NET 4.0 installation problem. We uninstalled and reinstalled the framework on all the computers that had this issue and it fixed the problem.