Использование DataGridCheckBoxColumn - выдает необработанное исключение

Это происходит, когда DataGridCheckBoxColumn используется в DataGrid и привязан к логическому свойству в модели поддержки. Если щелкнуть столбец и установить / снять флажки - он ведет себя так, как ожидалось, - но затем, когда я закрываю главное окно, выдается исключение. Этого не происходит, когда используются и взаимодействуют только текстовые столбцы. Этого также не произойдет, если я вообще НЕ взаимодействую с столбцом флажков и просто закрою окно. Это происходит только тогда, когда я закрываю окно ПОСЛЕ того, как я взаимодействовал со столбцом флажка.

Среда разработки:

Операционные системы:
1. Arch Linux, Gnome 3, Wayland.
2. Windows 10 Pro


Разработчик: dotnet core 3.1.103
IDE: VS Code

Действия по воспроизведению:

Общая процедура использования DataGrid описана в учебной статье: Начало работы с Avalonia DataGrid.

Единственные изменения, которые я внес в статью, - это добавление DataGridCheckBoxColumn в DataGrid и добавление логического свойства IsChecked к классу модели "Person", используемому в учебнике, а затем их связывание.

Итак, ключевые шаги:

  1. $ dotnet new avalonia.mvvm
  2. В файле *csproj выберите версии всех включенных в Avalonia до 0.9.10, так как это версия DataGrid, которую я использую.
  3. $ dotnet add package Avalonia.Controls.DataGrid
  4. В App.xaml добавьте стиль:
    <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/>
  5. Добавьте следующее свойство к классу модели "Person" - остальная часть кода осталась нетронутой и соответствует руководству по ссылке:
 public bool IsChecked
        {get;set;}
  1. Добавьте DataGridCheckBoxColumn в DataGrid и привяжите его, как показано ниже (остальные столбцы не затронуты и соответствуют связанному руководству):
<DataGrid.Columns>
        <DataGridTextColumn Header="First Name" 
                            Binding="{Binding FirstName}" 
                            Width="2*" />
        <DataGridTextColumn Header="Last Name" 
                            Binding="{Binding LastName}" 
                            Width="2*" />
        <DataGridTextColumn Header="Department" 
                            Binding="{Binding DepartmentNumber}" 
                            Width="*" />

        <DataGridCheckBoxColumn Header="IsChecked" 
                            Binding="{Binding IsChecked}" 
                            Width="*" />

    </DataGrid.Columns>
  1. Затем, когда я запускаю приложение (либо из командной строки, либо из vscode), графический интерфейс отображается, как ожидалось, со всеми столбцами и значениями, и обычно отображается дополнительный столбец флажка. __ Когда я нажимаю в столбце флажков - флажки устанавливаются и снимаются, как и ожидалось (хотя требуется один дополнительный щелчок). Но затем, когда я закрываю окно, щелкнув "X" в правом верхнем углу - именно тогда происходит необработанное исключение - НЕ до этого.

Полный текст исключения:

Необработанное исключение. System.InvalidOperationException: коллекция была изменена; операция перечисления может не выполняться. в System.Collections.Generic.List`1.Enumerator.MoveNextRare() в Avalonia.Collections.AvaloniaList`1.Enumerator.MoveNext() в System.Linq.Enumerable.OfTypeIterator[TResult](источник IEnumerable)+ в MoveNext Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement. OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs e) в Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls. Контроль.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls. Контроль.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls. Контроль.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls. Контроль.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Visual.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.Control.OnDetachedFromVisualTreeCore (VisualTreeAttachmentEventArgs е) при Avalonia.Controls.TopLevel.HandleClosed () в Avalonia.Controls.WindowBase.HandleClosed() в Avalonia.Controls.Window.HandleClosed() в Avalonia.X11.X11Window.Cleanup() в Avalonia.X11.X11Window.Dispose() в Avalonia.X11.X11Window.OnEventSync(X11Window.OnEventSync) в Avalonia.X11.X11Window.OnEvent(XEvent ev) в Avalonia.X11.X11PlatformThreading.HandleX11(CancellationToken cancellationToken) в Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationTokread.Dispatcher.MainLoop(CancellationToken cancellationToken) в Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) в Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesign, ShutdownModed [buildtime], ShutdownMode, [buildtime], ShutdownMode, [buildtime] (String[] args) в /home/[myusername provided/[pathtoproject]/Program.cs:line 14

Код для класса Person:

public class Person
    {
        public int DepartmentNumber { get; set; }

        public string DeskLocation{ get; set; }

        public int EmployeeNumber { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public bool IsChecked
        {get;set;}
    }

Код для MainWindowViewModel, который действует как код для MainWindow и использует класс Person, указанный выше, для размещения ObservableCollection и предоставления его как общедоступного свойства с именем People. DataGrid привязан к этому свойству People, которое служит коллекцией класса Person (свойства которого представлены различными столбцами, такими как DataGridTextColumn и DataGridCheckBoxColumn):

public class MainWindowViewModel : ViewModelBase
    {
        public ObservableCollection<Person> People { get; set;}

        public MainWindowViewModel()
        {
            People = new ObservableCollection<Person>(GenerateMockPeopleTable());
        }

        private ObservableCollection<Person> GenerateMockPeopleTable()
        {
            var defaultPeople = new ObservableCollection<Person>()
            {
                new Person()
                {
                    FirstName = "Pat", 
                    LastName = "Patterson", 
                    EmployeeNumber = 1010,
                    DepartmentNumber = 100, 
                    DeskLocation = "B3F3R5T7",
                    IsChecked = false
                },
                new Person()
                {
                    FirstName = "Jean", 
                    LastName = "Jones", 
                    EmployeeNumber = 973,
                    DepartmentNumber = 200, 
                    DeskLocation = "B1F1R2T3",
                    IsChecked = true
                },
                new Person()
                {
                    FirstName = "Terry", 
                    LastName = "Tompson", 
                    EmployeeNumber = 300,
                    DepartmentNumber = 100, 
                    DeskLocation = "B3F2R10T1",
                    IsChecked = false
                }
            };

            return defaultPeople;
        }
    }

ОБНОВЛЕНИЕ: я отказался от поиска решения. Вот моя работа:

Вместо использования DataGridCheckBoxColumn (который также имел дополнительное раздражение, поскольку его проверяли только при двойном щелчке - я использую DataGridTemplateColumn. Он решает указанную выше проблему исключения - а также имеет желаемое свойство проверки одним щелчком мыши.

<DataGridTemplateColumn Header="Select Todo">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsChecked}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

2 ответа

Заменить GenerateMockPeopleTable() с участием GenerateMockPeopleTable().ToList() и проверьте, решена ли проблема.

Я думаю, ваша проблема связана с используемой коллекцией, а не с флажком. ты должен позвонить.ToList()после вашей коллекции. проверьте следующую ссылку: Коллекция была изменена; операция перечисления может не выполняться

Другие вопросы по тегам