我有视觉工作室2017,创建自定义控件,如自定义组合框扩展组合框无法从设计器工具框加载。使用代码生成自定义组合框,添加它作为控件,然后继续...它工作正常组合框中的默认自动完成是不够的所以我使用另一个来搜索子串并在自动建议中更灵活/追加模式。
如果我加载另一个做同样事情的项目它工作正常,所以我不确定这个问题对我来说。我已经尝试了64/32位,重新编写控件十几次,清理并重新构建,它显示在工具箱中,使用代码构建和添加控件确认它工作正常。
为什么VS2017不允许我将它从工具箱拖到我的表单上,它总是给出错误:“无法加载工具箱项'SuggestComboBox'。它将从工具箱中删除。
我已经尝试了许多其他帖子解决方案,但似乎都没有。如何编译解决方案,代码添加控件并正常工作,但工具箱/设计器在使用GUI时仍然失败?这是有问题的,因为我不能使用设计师,但是不可能看到可能出错的地方。
有任何想法吗? < - 我还在互联网上运行了一个工作示例项目,将执行相同操作的文件(子类组合框)复制到我的项目中,它也失败了......这可能是vs2017错误或某种我错过的步骤设置这个?
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
}
}
感谢Reza Aghaei,您的建议以及我学到的东西是x64 / x86版本是用户控件的问题。您需要为您的用户控件创建一个单独的项目,使用x86构建它们并将它们加载到您的项目中(总是使用32位),但由于我的是同一个项目,我让x64针对设计师进行了克制。
由于其他一切仍然可以从代码,可执行文件到已经包含我的控制/用户控制代码的设计器表单中运行良好,因此几乎不可能弄清楚什么是错的。
构建32位并删除所有内容然后重新编译。问题解决了,只花了几个小时:S。 VS2017。