Пользовательский элемент управления.NET (ToolStripControlHost) наносит ущерб дизайнеру
Мне нужно иметь MaskedTextBox в ToolStrip, который не включен по умолчанию, поэтому я последовал совету, который нашел в Интернете, и создал собственный элемент управления, который наследуется от ToolStripControlHost. То, что я создал, прекрасно работает, когда я запускаю приложение, но это действительно портит дизайнера. Под "испорченным" я подразумеваю, что пользовательский элемент управления (наряду с некоторыми другими) исчезает из ToolStrip. Кроме того, я больше не могу добавлять новые элементы управления в ToolStrip и не могу выбрать существующие элементы управления в ToolStrip для их редактирования.
Вот мой класс.
[DesignerCategory("code")]
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public partial class ToolStripMaskedTextBox : ToolStripControlHost
{
public MaskedTextBox MaskedTextBox
{
get { return Control as MaskedTextBox; }
}
public ToolStripMaskedTextBox()
: base(CreateControlInstance()) { }
private static Control CreateControlInstance()
{
MaskedTextBox mtb = new MaskedTextBox();
mtb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
mtb.MinimumSize = new System.Drawing.Size(100, 16);
mtb.PasswordChar = '*';
return mtb;
}
}
Буду признателен за любую помощь в том, что я могу сделать неправильно, что доставит дизайнеру трудное время.
Информация о дополнении
Теперь, когда я открываю свой файл класса в Visual Studio, я получаю страницу предупреждения со следующей ошибкой:
Constructor on type 'System.Windows.Forms.ToolStripControlHost' not found.
Дополнение Info 2
Проблема возникает только после построения решения. Я могу заставить дизайнер работать правильно, изменив файл Form.Designer.cs даже самым маленьким способом. Как добавление одного пробела. С этого момента дизайнер будет работать нормально. Пока я не построю решение. Затем дизайнер снова зависает. Ни один из элементов управления в форме не может быть отредактирован.
4 ответа
Согласно исключению
Constructor on type 'System.Windows.Forms.ToolStripControlHost' not found.
Я нашел некоторую информацию на форуме MSDN.
Это происходит потому, что ToolStripControlHost
У класса нет конструктора без параметров.
Чтобы решить эту проблему, вы можете создать свой собственный ToolStripControlHost с конструктором без параметров и сделать ToolStripMaskedTextBox унаследованным от вашего ToolStripControlHost. Попробуйте что-то вроде следующего
//Declare a class that inherits from ToolStripControlHost.
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripMaskedTextBox : MyCustomToolStripControlHost
{
// Call the base constructor passing in a MaskedTextBox instance.
public ToolStripMaskedTextBox() : base(CreateControlInstance()) { }
public MaskedTextBox MaskedTextBox
{
get
{
return Control as MaskedTextBox;
}
}
private static Control CreateControlInstance()
{
MaskedTextBox mtb = new MaskedTextBox();
mtb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
mtb.MinimumSize = new System.Drawing.Size(100, 16);
mtb.PasswordChar = '*';
return mtb;
}
}
public class MyCustomToolStripControlHost : ToolStripControlHost
{
public MyCustomToolStripControlHost()
: base(new Control())
{
}
public MyCustomToolStripControlHost(Control c)
: base(c)
{
}
}
Это исправит проблему с вашим исключением.
Проблема с конструктором форм (ToolStripMaskedTextBox не отображается после запуска приложения) не решена, но вы можете закрыть конструктор и снова открыть файл.
Тогда вы можете продолжать без проблем.
Надеюсь это поможет
Я использовал решение dknaack, но поместил MyCustomToolStripControlHost
Класс в отдельном файле в пространстве имен System.Windows.Forms. А также...
Первое: это работает - не исключение. Затем: мой контроль виден и в дизайнере, так что это джекпот.
Я нашел решение дизайнерской проблемы. https://dobon.net/vb/dotnet/control/tschdesigneravail.html (японский)
Все, что вам нужно, это просто создать класс, производный от ToolStrip, и заменить его.
class DesignerFriendlyToolStrip : ToolStrip { }
var ts = new DesignerFriendlyToolStrip();
ts.Items.Add(toolStripMaskedTextBox);
form.Controls.Add(ts);
Я не знаю, почему это эффективно. Кто-нибудь знает...?
FWIW: Мне также удалось использовать решение dknaack выше, но только после того, как я понял, что искал пользовательский элемент управления ToolStrip в неправильном месте. Пользовательский элемент управления не отображается в самой панели инструментов. Скорее, он отображается в раскрывающемся списке компонентов под "Добавить ToolStripButton", который появляется в ToolStrip при его выборе (в конструкторе).
В этой ссылке ответ состоял в том, что объекты, которые реализуют интерфейс "бла", должны иметь конструктор без параметров. Попробуйте.