【问题标题】:Custom ComboBox: prevent designer from adding to Items自定义组合框:防止设计师添加到项目
【发布时间】:2019-03-24 01:35:06
【问题描述】:

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

代码很小。

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"});

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

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

如何抑制这种行为?

【问题讨论】:

    标签: c# winforms combobox user-controls designer


    【解决方案1】:

    当您将控件放在表单上时,构造函数代码和任何加载代码都会运行。那里的任何更改属性值的代码都将在设计时执行,因此将写入您放置控件的表单的 Designer.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;
    }
    

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

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

    【讨论】:

    • 谢谢你的提醒,我差点被抓住了!
    • 添加“|| LicenseManager.UsageMode == LicenseUsageMode.Designtime”解决了我遇到的问题。出于某种原因,仅检查 DesignMode 并不总是有效..
    【解决方案2】:

    问题在于构造函数中的绑定是由设计器运行的。您可以尝试将其移至 Initialise 或 Loaded 事件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      相关资源
      最近更新 更多