Подскажите, что может произойти в `Windows Forms UserControl` при добавлении кнопки?

Рейтинг: 0Ответов: 0Опубликовано: 21.02.2023

Два дня не могу разобраться почему зависает расширение для "Visual Studio 2022(Version 17.4.5 x 64)".

В этой справке показано как добавить кастомную страницу параметров Tools->Options, к сожалению там только "Windows Forms". Добавил в UserControl DataGridView, установил 3 кнопки - на этом все закончилось. Если отредактировать ячейку и "потерять фокус" - клик на "Ok" или "Cancel" ожидаемо закрывает окно параметров. Но если отредактировать и оставить фокус внутри любой ячейки, как на этой картинке, VS полностью зависает и разгоняет процессор.

введите сюда описание изображения

Методом исключений пришел к неожиданному выводу - САМО НАЛИЧИЕ [КНОПКИ], ДАЖЕ БЕЗ ОБРАБОТЧИКОВ, не дает нормально выйти из окна Option.

Собрал новое расширение, исключив весь код, и не могу понять что теперь делать? Если есть возможность, вот VSIXExtensionProject архив - проект запускает отдельный instance VS в dev-режиме, или ниже несколько файлов - там толком кода нет, на кнопке ни одного обработчика, но ничего не работает.

Options.cs / OptionsUserControl.cs / OptionsUserControl.Designer.cs / VSIXWithDataGridViewPackage.cs

///// --- Options.cs --- /////

using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VSIXWithDataGridView
{
public class Options : DialogPage
{
    [Category("Templates")]
    [DisplayName("Query Templates")]
    [Description("Open and edit the collection ...")]
    public List<TemplateInfo> Templates { get; set; } = new List<TemplateInfo>() {
        new TemplateInfo(){Title = "Google", Template = "https://www.google.com/"},
        new TemplateInfo(){Title = "Microsoft", Template = "https://www.microsoft.com/"}
    };

    private readonly BindingList<TemplateInfo> bindTemplates = new BindingList<TemplateInfo>();

    private bool isOpened = false;

    protected override void OnActivate(CancelEventArgs e)
    {
        base.OnActivate(e);
        if (isOpened) return;
        isOpened = true;
        var tpls = Templates;
        bindTemplates.Clear();
        foreach (var item in tpls) bindTemplates.Add(item.Clone());
    }

    protected override void OnApply(PageApplyEventArgs e)
    {
        var tpls = Templates;
        tpls.Clear();
        foreach (var item in bindTemplates) tpls.Add(item.Clone());
        isOpened = false;
        base.OnApply(e);
    }

    protected override void OnClosed(EventArgs e)
    {
        isOpened = false;
        base.OnClosed(e);
    }

    protected override System.Windows.Forms.IWin32Window Window => new OptionsUserControl(bindTemplates);
}

public class TemplateInfo
{
    public string Title { get; set; }
    public string Template { get; set; }
    public TemplateInfo Clone() => new TemplateInfo() { Title = this.Title, Template = this.Template };
}
}

///// --- OptionsUserControl.cs --- /////

using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VSIXWithDataGridView
{
public partial class OptionsUserControl : UserControl
{
    public OptionsUserControl(BindingList<TemplateInfo> tpls)
    {
        InitializeComponent();
        this.dataGridView1.DataSource = tpls;
    }
}
}

///// --- OptionsUserControl.Designer.cs --- /////

namespace VSIXWithDataGridView
{
partial class OptionsUserControl
{
    private System.ComponentModel.IContainer components = null;

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private void InitializeComponent()
    {
        this.dataGridView1 = new System.Windows.Forms.DataGridView();
        this.button1 = new System.Windows.Forms.Button();  // <<<=
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
        this.SuspendLayout();
        // 
        // dataGridView1
        // 
        this.dataGridView1.AllowUserToAddRows = false;
        this.dataGridView1.AllowUserToDeleteRows = false;
        this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.Window;
        this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        this.dataGridView1.Location = new System.Drawing.Point(14, 14);
        this.dataGridView1.Name = "dataGridView1";
        this.dataGridView1.Size = new System.Drawing.Size(326, 148);
        this.dataGridView1.TabIndex = 0;
        // 
        // button1  // <<<=
        // 
        this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
        this.button1.Location = new System.Drawing.Point(14, 168);
        this.button1.Name = "button1";
        this.button1.Size = new System.Drawing.Size(218, 63);
        this.button1.TabIndex = 1;
        this.button1.Text = "Любая кнопка вызывает зависание страницы параметров";
        this.button1.UseVisualStyleBackColor = true;
        // 
        // OptionsUserControl
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.AutoSize = true;
        this.Controls.Add(this.button1);
        this.Controls.Add(this.dataGridView1);
        this.Name = "OptionsUserControl";
        this.Size = new System.Drawing.Size(646, 436);
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
        this.ResumeLayout(false);
    }

    private System.Windows.Forms.DataGridView dataGridView1;
    private System.Windows.Forms.Button button1; // <<<=
}
}

///// --- VSIXWithDataGridViewPackage.cs --- /////

using Microsoft.VisualStudio.Shell;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Task = System.Threading.Tasks.Task;

namespace VSIXWithDataGridView
{
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(VSIXWithDataGridViewPackage.PackageGuidString)]
[ProvideOptionPage(typeof(Options), "XXX XXX XXX", "General", 0, 0, true)]
public sealed class VSIXWithDataGridViewPackage : AsyncPackage
{
    public const string PackageGuidString = "724b772a-926b-4012-8bf8-19858cad58d1";

    protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
    {
        await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
    }
}
}

UPD:
Дело не в кнопках. Любой элемент, например картинка, добавленный вторым/третьим/десятым мешает нормально деактивировать страницу параметров.

<UserControl>.Controls.Add(this.dataGridView);
<UserControl>.Controls.Add(<ВсеЧтоУгодно>);

К тому же неясно: Почему VS самовольно захватывает и обрабатывает Enter/Esc(закрывает окно параметров), когда фокус находится в редактируемой ячейке?

Сэмулировать ошибку в простом приложении(Form + второй Form.ShowDialog()) не удалось - даже намека на ошибку нет.

Ответы

Ответов пока нет.