更新以反映我的请求的更多功能描述。
从功能上讲,我需要一个不会直接从ComboBox
类继承的只读System.Windows.Forms.ComboBox
。我需要文本框部分是只读的,因此用户可以复制输入到框中的文本但不能更改它。这不是使用DropDown
vs DropDownList
模式的情况。
使用此article和一些实验,我已经处理了文本框部分,但仍需要防止由于下面列出的技术原因而对下拉组件进行更改。我仍然需要以下其中一项:
ComboBox
上的下拉按钮 - 以防止其打开ComboBox
时打开下拉列表我在我的应用程序中使用KryptonToolkit来获得视觉上的美观。对于KryptonComboBox
控件,它有一个内部的,扩展的System.Windows.Forms.ComboBox
类来拦截绘制调用。它公开了对ComboBox
对象的访问权限,因此我可以访问它Handle
。
我使用A Complete Read Only ComboBox代码作为基础来创建KryptonComboBox
的只读版本。您必须使用KryptonComboBox.Handle
来获取Windows控件的实际句柄,而不是在SendMessage()
调用中使用KryptonComboBox.ComboBox.Handle
。通过这样做,我能够正确地在ComboBox的文本框部分设置只读模式。
BUT!由于扩展控件的基类是KryptonComboBox
而不是ComboBox
,因此当WndProc()
被调用时,它是KryptonComboBox
的消息。因此,当处于只读模式时,我无法阻止控件对所单击的下拉项执行操作(更改选择)。
如何拦截(并可能忽略)来自现有ComboBox控件的WM_COMMAND消息。具体来说,我希望在某些情况下忽略一条消息273链。有没有办法在函数上对一个“外部”ComboBox
控件做同样的事情,我可以从一个继承的控件?由于我Handle
有ComboBox
,我可以使用SetWindowsHookEx()
之类的内容拦截邮件吗?
答案 0 :(得分:0)
所以我找到了一个解决方案,用于“插入”控件的命令消息并能够中断它们。它涉及使用System.Windows.Forms.NativeWindow
类来创建ComboBox
的监听器,这是(根据我的理解)称为子类。
听众类:
private class ComboBoxListener : NativeWindow, IDisposable {
private ComboBox m_oComboBox;
private EventHandler m_oComboBox_HandleCreated;
private EventHandler m_oComboBox_HandleDestroyed;
public ComboBoxListener(ComboBox oComboBox) {
// Save the combobox and assign the handle if it's already created
m_oComboBox = oComboBox;
if (m_oComboBox.IsHandleCreated) {
AssignHandle(m_oComboBox.Handle);
}
// Subscribe to the handle events of the combobox
m_oComboBox.HandleCreated += m_oComboBox_HandleCreated = new EventHandler(ComboBox_HandleCreated);
m_oComboBox.HandleDestroyed += m_oComboBox_HandleDestroyed = new EventHandler(ComboBox_HandleDestroyed);
}
~ComboBoxListener() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool bDisposing) {
if (bDisposing && (m_oComboBox != null) && !m_oComboBox.IsDisposed) {
// Unsubscribe from the combo box
m_oComboBox.HandleCreated -= m_oComboBox_HandleCreated;
m_oComboBox.HandleDestroyed -= m_oComboBox_HandleDestroyed;
}
m_oComboBox = null;
// If a handle is currently assigned, release it
if (this.Handle != IntPtr.Zero) {
ReleaseHandle();
}
}
private void ComboBox_HandleCreated(object sender, EventArgs e) {
AssignHandle(m_oComboBox.Handle);
}
private void ComboBox_HandleDestroyed(object sender, EventArgs e) {
ReleaseHandle();
}
protected override void WndProc(ref Message m) {
// Do checks for whether to ignore the message
// If ignoring, just call return and skip the base.WndProc(ref m) call
base.WndProc(ref m);
}
}
然后在KryptonComboBox
的派生类的构造函数中,我添加了:
m_oComboBoxListener = new ComboBoxListener(this);
并在被覆盖的Dispose(bool disposing)
:
// Dispose the listener
if (disposing && (m_oComboBoxListener != null)) {
m_oComboBoxListener.Dispose();
}
m_oComboBoxListener = null;