AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.42k stars 2.2k forks source link

ArgumentOutOfRangeException when selecting a DataGrid item, after changing DataGrid.ItemsSource #16164

Open jwl4 opened 3 months ago

jwl4 commented 3 months ago

Describe the bug

If a DataGrid.ItemsSource property is assigned in a LostFocus event, clicking an item in the DataGrid will throw ArgumentOutOfRangeException

To Reproduce

    <DockPanel>
        <Panel DockPanel.Dock="Top">
            <Border Margin="20">
                <TextBox 
                    Text="Click this textbox, then select an item in the list"
                    x:Name="Text" 
                    LostFocus="Text_LostFocus"
                    Width="350"
                    Padding="10" />
            </Border>
        </Panel>
        <DataGrid
            x:Name="Grid"
            AutoGenerateColumns="True"
            IsReadOnly="True">
        </DataGrid>
    </DockPanel>
using System.Collections.Generic;
using Avalonia.Controls;
using Avalonia.Interactivity;

public partial class CrashyWindow : Window
{

    public CrashyWindow()
    {
        InitializeComponent();
        Grid.ItemsSource = MakeAList();
    }

    public void Text_LostFocus(object sender, RoutedEventArgs args)
    {
        // setting a grid's ItemsSource property in a LostFocus event will cause the grid
        //   to throw a System.ArgumentOutOfRangeException when an item in the grid is clicked
        // (tab doesn't cause a problem, nor does clicking in the grid's header row)
        Grid.ItemsSource = MakeAList();
    }

    private static List<string> MakeAList()
    {
        return ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
    }

}

Expected behavior

Maybe the DataGrid ought to process the changes in ItemsSource before passing the MouseDown to the DataGridCell?

Avalonia version

11.0.11

OS

Linux

Additional context

I tried using ObservableCollection instead of List, per the example at , but that gave the same exception.

I was attempting to parse a date in a textbox LostFocus event, then update the DataGrid using that date as a parameter. It's entirely possible that there's a better way to accomplish this.

timunie commented 3 months ago

I feel like AutoGenerateColumns may be the issue here.

jwl4 commented 1 month ago

You are correct, @timunie. When the columns are defined using instead of using AutoGenerateColumns, the ArgumentOutOfRangeException goes away.

AutoGenerateColumns seems like a great shortcut, but I'm finding that it probably won't give enough control of layout for the kinds of DataGrids I'm using.

Thank you for your response, it was helpful!