3
votes

I am fairly new to WPF and MVVM and a newb in general, so thank you in advance for your patience.

I am using a custom class in my model, and I have an ObservableCollection of that custom object in my viewmodel. In the class' constructor, I am adding the object to the collection when it is instantiated. In my view, I am using a DataGrid that is bound to the collection to list all active instances of the class. I am trying to implement a drag-and-drop from the DataGrid onto a trash can icon that would allow a user to dispose of unneeded instances of the class.

The problem is that when you click anything in the DataGrid, the program immediately crashes with an ArgumentOutOfRange exception - ("The given DisplayIndex is out of range. DisplayIndex must be greater than or equal to 0 and less than Columns.Count." "Actual value was 0"). DisplayIndex seems to relate to the DataGrid column, so this exception is probably due to the fact that I am not displaying any columns in the traditional sense - in my DataGrid, AutoGenerateColumns is set to False, and I am displaying everything I need to display using a RowDetailsTemplate. (The reason for this is that the area where I am displaying the DataGrid is narrow, so I need a nested, item-specific grid to represent the item properly.) The DataGrid displays and syncs with the collection fine, but obviously has some issues. I have read dozens of links on DataGrid crashes, and haven't found anything involving this exception.

My desired behavior is to pass the custom object represented by the DataGrid item to a target when I drag and drop it. I don't care which "column" they clicked or anything else - I just need a way to pass either an object reference or a SelectedIndex (the items index in the collection) to a method in the viewmodel.

Thank you in advance for any help! The offending bit of code (XAML) seems to be:

<ScrollViewer DockPanel.Dock="Bottom" Margin="2" Width="180" ScrollViewer.VerticalScrollBarVisibility="Auto">
            <DataGrid ItemsSource="{Binding Path=myCollection, Mode=OneWay}" AutoGenerateColumns="False" RowDetailsVisibilityMode="Visible" HeadersVisibility="None">
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate DataType="model:myClass">
                        <Border CornerRadius="10" Background="AliceBlue">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="50" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding MyString1}" FontSize="21" VerticalAlignment="Bottom" />
                                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding MyCustomProperty, Converter={StaticResource MyIValueConverter}}" VerticalAlignment="Bottom" />
                                <TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding MyString2}" TextWrapping="Wrap" />
                                <Image Source="/Resources/image1.png" Grid.Column="2" Grid.Row="0">
                                    <Image.DataContext>
                                        <Properties:Resources/>
                                    </Image.DataContext>
                                </Image>
                                <Image Source="/Resources/image2.png" Grid.Column="2" Grid.Row="1">
                                    <Image.DataContext>
                                        <Properties:Resources/>
                                    </Image.DataContext>
                                </Image>
                            </Grid>
                        </Border>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
        </ScrollViewer>
1

1 Answers

3
votes

The issue was indeed because I am not generating any "traditional" columns. This is apparently a known bug, documented here: Microsoft Bug Report

As a workaround, I just defined an invisible column within the DataGrid and it seems to behave properly now:

<DataGrid.Columns>
     <DataGridTemplateColumn Visibility="Hidden" />
</DataGrid.Columns>