【问题标题】:How to disable read operation from combobox in winform?如何在winform中禁用组合框的读取操作?
【发布时间】:2013-12-12 14:52:55
【问题描述】:

我知道 wpf 中的命令,但它在 winform 中的等价物是什么?

        cboclient.IsHitTestVisible = false;
        cboclient.Focusable = false;

使用此命令,组合框未被禁用,但用户无法打开它以读取数据。我如何在 winfrom 中完成此操作?谢谢

详细信息:当表单最初加载时,我的表单上有 3 个组合框,唯一的第三个组合框无法打开以读取数据。当用户在前两个组合框中选择值时,根据这两个值,第三个组合框被启用以显示来自 db 的数据。

注意:这里我不想禁用第三个组合框。因为它会给用户错误的表达。

【问题讨论】:

  • 你试过cboclient.Enabled = false;吗?
  • yes....它禁用组合框
  • 这不是你想要的?请描述你的目标......
  • 我只想要 db 中没有记录。那么组合框的状态是用户无法打开它进行阅读..它保持活动状态并启用
  • 那么在上面的.Enabled = false; 行周围添加if 语句不起作用?您开始了解您尚未公开的应用程序的细节,这实际上是我们无法猜测的......

标签: c# wpf winforms combobox


【解决方案1】:

您可以捕获消息WM_MOUSEACTIVATE 并将其丢弃,以防止用户通过鼠标聚焦组合框并防止命中测试。捕捉消息WM_SETFOCUS 以防止用户通过键盘聚焦组合框。试试这个代码:

public class ComboBoxEx : ComboBox
{    
    public ComboBoxEx(){
        IsHitTestVisible = true;
    }
    public bool IsHitTestVisible { get; set; }
    public bool ReadOnly { get; set; }
    protected override void WndProc(ref Message m)
    {            
        if (!IsHitTestVisible)
        {
            if (m.Msg == 0x21)//WM_MOUSEACTIVATE = 0x21
            {
                m.Result = (IntPtr)4;//no activation and discard mouse message
                return;
            }
            //WM_MOUSEMOVE = 0x200, WM_LBUTTONUP = 0x202
            if (m.Msg == 0x200 || m.Msg == 0x202) return;
        }
        //WM_SETFOCUS = 0x7
        if (ReadOnly && m.Msg == 0x7) return;
        base.WndProc(ref m);
    }
    //Discard key messages
    public override bool PreProcessMessage(ref Message msg)
    {
        if (ReadOnly) return true;
        return base.PreProcessMessage(ref msg);
    }
}
//Usage
comboBoxEx1.ReadOnly = true;
comboBoxEx1.IsHitTestVisible = false;

【讨论】:

  • 优秀的答案。它展示了如何通过在 WPF 中设置 2 个属性来实现某些东西,这需要一堆可怕的 hack,在 winforms 中到处都是神奇的数字和奇怪的东西。
  • @HighCore 是的,我认为这足够相关,可以放入您的收藏中,但这不是 winforms 的底层,那里有许多更复杂的代码,所有这些复杂的代码使用 WPF 可以变得更简单,这并不奇怪,因为 WPF 是一个更高级别的库,当然是下一个 UI 技术:|
  • 真正令人恶心的是那些0x2000x202...这到底是什么?他们为什么不创建一个怪胎enum 或其他什么?看起来像是回到了与 Windows 95 API 交互的 VB6 时代
  • @HighCore 实际上有一个类(非官方/标准)包含所有 win32 内容,包括此类常量(定义为枚举或命名常量),我只是在生产代码中发布了这个答案中的常量,我们最好使用那个类。
【解决方案2】:

您可以在 OnSelectionChangedSelectionChanged 事件上使用 if 语句。

  private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      //here your if statement
    }

【讨论】:

    【解决方案3】:

    您可以使用以下代码:

    cboclient.DropDownStyle = ComboBoxStyle.DropDownList;
    cboclient.DropDownHeight = 1;
    cboclient.DropDownWidth = 1;
    cboclient.TabStop = false;
    

    用于将组合框显示为您可以使用的只读组合框:

    cboclient.FlatStyle = FlatStyle.Popup;
    

    cboclient.FlatStyle = FlatStyle.Flat;
    

    【讨论】:

      猜你喜欢
      • 2020-01-26
      • 2018-05-21
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      相关资源
      最近更新 更多