我有Visual Studio 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
}
}
答案 0 :(得分:0)
感谢Reza Aghaei,您的建议以及我所学到的x64 / x86版本也是用户控件的问题。您要么为用户控件需要一个单独的项目,然后使用x86进行构建并将它们加载到您的项目中(始终使用32位),但是由于我的项目是同一个项目,而x64却使设计人员陷入了困境。
由于从代码,可执行文件到已经包含我的控件/用户控件代码的设计器表单,其他所有一切仍然运行良好,因此几乎不可能找出问题所在。
构建32位并删除所有内容,然后重新编译。问题解决了,只花了几个小时:S。 VS2017。