У меня есть Visual Studio 2017, создание пользовательских элементов управления, таких как настраиваемое поле со списком, которое расширяет поле со списком, не загружается из панели инструментов дизайнера. Он отлично работает, используя код для генерации настраиваемого поля со списком, добавления его в качестве элемента управления и продолжения ... Стандартное автозаполнение в поле со списком не подходит, поэтому я использовал другой для поиска подстрок и был более гибким в автоматическом предложении / добавить режим.
Если я загружаю другой проект, который делает то же самое, он работает нормально, поэтому я не уверен, в чем проблема для меня. Я пробовал 64/32 бит, переписывал элемент управления десятки раз, очищал и перестраивал, он показывается в наборе инструментов, подтверждаю, что он работает нормально, используя код для сборки и добавления элемента управления.
Почему VS2017 не позволяет мне перетащить его из ящика для инструментов на мою форму, он всегда выдает ошибку: «Не удалось загрузить элемент панели инструментов« SuggestComboBox ». Он будет удален из панели инструментов.
»
Я пробовал многие другие решения для постов, и ни одно из них, похоже, не работает. Как это возможно, решение компилируется, код добавляет элемент управления и работает нормально, но набор инструментов / дизайнер продолжает работать, когда я использую графический интерфейс? Это проблематично, потому что я не могу использовать конструктор, но невозможно понять, что может быть не так.
Есть идеи? <- Я также запустил рабочий пример проекта из Интернета, скопировал файл, который делает то же самое (поле со списком подкласса), в мой проект, и он тоже потерпел неудачу ... это может быть ошибка vs2017 или какой-то шаг, который я пропустил настраиваете это? </p>
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Windows.Forms;
//@note DataItem is a custom class stored in combo box to have key/value pairs
namespace System.Windows.Forms
{
[ToolboxItem(true)]
partial class SuggestComboBox : ComboBox
{
#region fields and properties
private readonly ListBox _suggLb = new ListBox { Visible = false, TabStop = false };
private readonly BindingList<DataItem> _suggBindingList = new BindingList<DataItem>();
public int SuggestBoxHeight
{
get { return _suggLb.Height; }
set { if (value > 0) _suggLb.Height = value; }
}
#endregion
/// <summary>
/// ctor
/// </summary>
public SuggestComboBox()
{
_suggLb.DataSource = _suggBindingList;
_suggLb.Click += SuggLbOnClick;
ParentChanged += OnParentChanged;
}
/// <summary>
/// the magic happens here ;-)
/// </summary>
/// <param name="e"></param>
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
if (!Focused) return;
_suggBindingList.Clear();
_suggBindingList.RaiseListChangedEvents = false;
//do a better comparison then just 'starts with'
List<DataItem> results = new List<DataItem>();
foreach(object item in Items)
{
//data item or regular
if( item.ToString().ToLower().Contains( Text.Trim().ToLower()))
{
results.Add((DataItem)item);
}
}
//add to suggestion box (@todo may need data items...)
foreach (DataItem result in results)
{
_suggBindingList.Add(result);
}
_suggBindingList.RaiseListChangedEvents = true;
_suggBindingList.ResetBindings();
_suggLb.Visible = _suggBindingList.Any();
if (_suggBindingList.Count == 1 &&
_suggBindingList.Single().ToString().Length == Text.Trim().Length)
{
Text = _suggBindingList.Single().ToString();
Select(0, Text.Length);
_suggLb.Visible = false;
}
//handle zindex issue of suggestion box
this.BringToFront();
_suggLb.BringToFront();
}
#region size and position of suggest box
/// <summary>
/// suggest-ListBox is added to parent control
/// (in ctor parent isn't already assigned)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnParentChanged(object sender, EventArgs e)
{
Parent.Controls.Add(_suggLb);
Parent.Controls.SetChildIndex(_suggLb, 0);
_suggLb.Top = Top + Height - 3;
_suggLb.Left = Left + 3;
_suggLb.Width = Width - 20;
_suggLb.Font = new Font("Segoe UI", 9);
}
protected override void OnLocationChanged(EventArgs e)
{
base.OnLocationChanged(e);
_suggLb.Top = Top + Height - 3;
_suggLb.Left = Left + 3;
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
_suggLb.Width = Width - 20;
}
#endregion
#region visibility of suggest box
protected override void OnLostFocus(EventArgs e)
{
// _suggLb can only getting focused by clicking (because TabStop is off)
// --> click-eventhandler 'SuggLbOnClick' is called
if (!_suggLb.Focused)
HideSuggBox();
base.OnLostFocus(e);
}
private void SuggLbOnClick(object sender, EventArgs eventArgs)
{
Text = _suggLb.Text;
Focus();
}
private void HideSuggBox()
{
_suggLb.Visible = false;
}
protected override void OnDropDown(EventArgs e)
{
HideSuggBox();
base.OnDropDown(e);
}
#endregion
#region keystroke events
/// <summary>
/// if the suggest-ListBox is visible some keystrokes
/// should behave in a custom way
/// </summary>
/// <param name="e"></param>
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
{
if (!_suggLb.Visible)
{
base.OnPreviewKeyDown(e);
return;
}
switch (e.KeyCode)
{
case Keys.Down:
if (_suggLb.SelectedIndex < _suggBindingList.Count - 1)
_suggLb.SelectedIndex++;
return;
case Keys.Up:
if (_suggLb.SelectedIndex > 0)
_suggLb.SelectedIndex--;
return;
case Keys.Enter:
Text = _suggLb.Text;
Select(0, Text.Length);
_suggLb.Visible = false;
return;
case Keys.Escape:
HideSuggBox();
return;
}
base.OnPreviewKeyDown(e);
}
private static readonly Keys[] KeysToHandle = new[] { Keys.Down, Keys.Up, Keys.Enter, Keys.Escape };
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// the keysstrokes of our interest should not be processed be base class:
if (_suggLb.Visible && KeysToHandle.Contains(keyData))
return true;
return base.ProcessCmdKey(ref msg, keyData);
}
#endregion
}
}