简体   繁体   中英

Clicking on the column name of the DataGrid generates System.InvalidOperationException

I have created the following DataGrid object in a WPF application.

<Border
    BorderBrush="Black"
    BorderThickness="2"
    ScrollViewer.VerticalScrollBarVisibility="Visible"
    ScrollViewer.HorizontalScrollBarVisibility="Visible"
    Width="1110"
    Height="355"
    Margin="0,10,0,0"
    Grid.Column="1"
    Grid.Row="6"
    Grid.ColumnSpan="3"
    HorizontalAlignment="Center">
    <DataGrid
        Name="datagrid"
        ItemsSource="{Binding ElementName=datagrid, Mode=OneWay}"
        CanUserSortColumns="True"
        CanUserResizeRows="True"
        HorizontalAlignment="Left"
        VerticalAlignment="Stretch"
        VerticalScrollBarVisibility="Visible"
        HorizontalScrollBarVisibility="Visible"
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        ScrollViewer.HorizontalScrollBarVisibility="Visible"
        IsReadOnly="True"
        Height="355"
        Width="1110"
        Grid.Column="1"
        Grid.Row="6"
        Grid.ColumnSpan="3">
    </DataGrid>
</Border>

As you can observe, the ItemSource is binded. So the way I populate the datagrid with values, is by calling an sql query which returns a table. The code below demonstrates this.

private void PullDataFiles(string connectionstring, string tablenamevalue, DataGrid mainwindowdatagrid, int orderboolean)
{
    string connString = connectionstring;

    if (orderboolean == 1)
    {
        string query = $"SELECT * FROM [dbo].[{tablenamevalue}] ORDER BY 1 DESC";

        using (SqlConnection conn = new SqlConnection(connString))
        {

            SqlCommand cmd = new SqlCommand(query, conn);
            conn.Open();

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            da.Fill(dt);
            mainwindowdatagrid.ItemsSource = dt.DefaultView;
       }
    }
}

So I am calling the method like:

PullDataFiles(SQLServerConnectionDetails(), TextBlock1.Text, datagrid, 0); //where datagrid is the DataGrid from XAML code posted above

Everything works fine. Except from the moment when me (and a random user of the application) will click accidentally the column name of the DataGrid. If the user clicks a bit further of the column name the whole column sorts successfully. However, when the user will click on top of the column name the application crashes by producing the following error:

System.InvalidOperationException: ' 'System.Windows.Documents.Run' is not a Visual or Visual3D.'

I would really appreciate your help on this matter.

One possible solution is to prevent user from clicking the Header. Meaning to disable any functionality of the header tab. This can be achieved by changing the style of the header like below:

<DataGrid>
...
    <DataGrid.Resources>
        <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="IsHitTestVisible" Value="False"/>
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </DataGrid.Resources>
</DataGrid

This will prevent the user from clicking on your columns and thus generating the error exception.

I guess the exception is generated because you call the datagrid many times, so it refreshes.

I know that my answer won't resolve your initial problem but it's a temporary solution.

I had the same error, in my case I removed all underscores from the DataGrid column name and the problem was solved.

Try a column names that contains only alphabetical characters and spaces.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM