Подскажите, что может произойти в `Windows Forms UserControl` при добавлении кнопки?
Два дня не могу разобраться почему зависает расширение для "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()
) не удалось - даже намека на ошибку нет.