自定义组合框:阻止设计器添加到项目



>我有一个自定义组合框控件,应该显示可用的网络摄像头列表。

代码相当小。

using System;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using DirectShowLib;
namespace CameraSelectionCB
{
public partial class CameraComboBox : ComboBox
{
protected BindingList<string> Names;
protected DsDevice[] Devices;
public CameraComboBox()
{
InitializeComponent();
Devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Names = new BindingList<string>(Devices.Select(d => d.Name).ToList());
this.DataSource = Names;
this.DropDownStyle = ComboBoxStyle.DropDownList;
}
}
}

但是,我遇到了几个错误。 首先,每当我放置此组合框的实例时,设计器都会生成以下代码:

this.cameraComboBox1.DataSource = ((object)(resources.GetObject("cameraComboBox1.DataSource")));
this.cameraComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cameraComboBox1.Items.AddRange(new object[] {
"HP Webcam"});

这会导致运行时出现异常,因为在设置数据源时不应修改项。即使我不触摸设计器中的 Items 属性,也会发生这种情况。

"HP网络摄像头"是当时我电脑上唯一的摄像头。

如何抑制此行为?

当您将控件放在窗体上时,构造函数代码和任何加载代码都将运行。其中任何更改属性值的代码都将在设计时执行,因此将编写在设计器中.cs即您放置控件的窗体中。
在对控件进行编程时,应始终牢记这一点。

我通过添加一个属性来解决此问题,该属性可用于检查代码是在设计时还是运行时执行。

protected bool IsInDesignMode
{
get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; }
}
protected BindingList<string> Names;
protected DsDevice[] Devices;
public CameraComboBox()
{
InitializeComponent();
if (InDesignMode == false)
{
// only do this at runtime, never at designtime...
Devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Names = new BindingList<string>(Devices.Select(d => d.Name).ToList());
this.DataSource = Names;
}
this.DropDownStyle = ComboBoxStyle.DropDownList;
}

现在绑定只会在运行时发生

尝试此操作时,不要忘记删除设计器.cs文件中生成的代码

问题是构造函数中的绑定由设计器运行。您可以尝试将其移动到初始化或加载事件

最新更新