Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单击空白区域时,如何防止选中列表框的最后一项_C#_.net_Winforms_Listbox - Fatal编程技术网

C# 单击空白区域时,如何防止选中列表框的最后一项

C# 单击空白区域时,如何防止选中列表框的最后一项,c#,.net,winforms,listbox,C#,.net,Winforms,Listbox,我有一个列表框,它并没有完全填满项目,在最后一个项目之后有一些空白区域。当我点击那个空白区域时,最后一个项目会被自动选中。并且该选择发生在MouseDown事件之前。我想阻止它发生 我可以在SelectedIndexChanged中的变量中保留当前选定的索引(只能选择一项),并在MouseDown中重置它,但在MouseDown和MouseUp之间,最后一项被选中,看起来不太好 单击空白区域时,如何防止最后一项被选中 顺便说一句,这是一个由所有者绘制的列表框,但我不确定它是否与此问题有关 pr

我有一个列表框,它并没有完全填满项目,在最后一个项目之后有一些空白区域。当我点击那个空白区域时,最后一个项目会被自动选中。并且该选择发生在
MouseDown
事件之前。我想阻止它发生

我可以在
SelectedIndexChanged
中的变量中保留当前选定的索引(只能选择一项),并在
MouseDown
中重置它,但在
MouseDown
MouseUp
之间,最后一项被选中,看起来不太好

单击空白区域时,如何防止最后一项被选中


顺便说一句,这是一个由所有者绘制的列表框,但我不确定它是否与此问题有关

private void listBox\u DrawItem(对象发送方,DrawItemEventArgs e)
{
if((e.State&DrawItemState.Selected)=DrawItemState.Selected)
{
e、 图形.圆角矩形(画笔.LightSteelBlue,e.Bounds);
}
其他的
{
e、 图形。填充矩形(画笔。白色,e。边界);
}
如果(_commands.Count>0)
{
KeyValuePair cmd=(KeyValuePair)_命令[e.Index];
//第一排
e、 Graphics.DrawString(cmd.Key、_cmdNameFont、brush.Black、e.Bounds.X、e.Bounds.Y+_cellPadding);
//第二排
e、 图形.抽绳(cmd.Value,
_cmdCommandFont,Brush.Black,e.Bounds.X+5,e.Bounds.Y+\u cmdNameFont.Height+\u cellPadding);
}
e、 DrawFocusRectangle();
}
私有void列表框\u MeasureItem(对象发送方,measureItemEventTarget e)
{
e、 ItemHeight=\u cmdNameFont.Height+\u cmdCommandFont.Height+\u cellPadding*2;
}

确保从OnMeasureItem返回正确的值


编辑:OwnerDrawVariable的工作方式似乎有所不同。
通常,如果单击空白,IndexFromPoint(命中测试)返回-1。 使用OwnerDrawVariable,它返回底部的项

你有两个选择

1) 您的物品高度相同,因此您可以使用OwnerDrawFixed解决问题

base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.ItemHeight = this.Font.Height + this.Font.Height + _cellPadding * 2;

2) 在较低的级别处理鼠标单击,并抛出空的空格。

确保从OnMeasureItem返回正确的值


编辑:OwnerDrawVariable的工作方式似乎有所不同。
通常,如果单击空白,IndexFromPoint(命中测试)返回-1。 使用OwnerDrawVariable,它返回底部的项

你有两个选择

1) 您的物品高度相同,因此您可以使用OwnerDrawFixed解决问题

base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.ItemHeight = this.Font.Height + this.Font.Height + _cellPadding * 2;

2) 在较低的级别上处理鼠标单击,并扔掉空的空间。

我有一个解决办法。您可以放置面板并根据屏幕高度、列表框高度动态更改其高度。在这种情况下,当您单击空白区域时,新面板将进行单击。

我有一个解决方法。您可以放置面板并根据屏幕高度、列表框高度动态更改其高度。在这种情况下,当您单击空白区域时,新面板将进行单击。

您可以通过检查鼠标按下消息来执行此操作,如果用户没有单击某个项目,则不让它处理该消息:

public class ListBoxEx : ListBox {
  private const int WM_LBUTTONDOWN = 0x201;

  protected override void WndProc(ref Message m) {
    int lParam = m.LParam.ToInt32();
    int wParam = m.WParam.ToInt32();
    if (m.Msg == WM_LBUTTONDOWN) {
      Point clickedPt = new Point();
      clickedPt.X = lParam & 0x0000FFFF;
      clickedPt.Y = lParam >> 16;
      bool lineOK = false;
      for (int i = 0; i < Items.Count; i++) {
        if (GetItemRectangle(i).Contains(clickedPt)) {
          lineOK = true;
        }
      }
      if (!lineOK) {
        return;
      }        
    }
    base.WndProc(ref m);
  }
}
公共类ListBoxEx:ListBox{
私有常量int WM_LBUTTONDOWN=0x201;
受保护的覆盖无效WndProc(参考消息m){
int lParam=m.lParam.ToInt32();
int wParam=m.wParam.ToInt32();
如果(m.Msg==WM_LBUTTONDOWN){
点击点PT=新点();
clickedPt.X=lParam&0x0000FFFF;
单击pt.Y=lParam>>16;
bool lineOK=false;
对于(int i=0;i

您可以通过检查鼠标按下消息,如果用户没有单击某个项目,则不让它处理该消息:

public class ListBoxEx : ListBox {
  private const int WM_LBUTTONDOWN = 0x201;

  protected override void WndProc(ref Message m) {
    int lParam = m.LParam.ToInt32();
    int wParam = m.WParam.ToInt32();
    if (m.Msg == WM_LBUTTONDOWN) {
      Point clickedPt = new Point();
      clickedPt.X = lParam & 0x0000FFFF;
      clickedPt.Y = lParam >> 16;
      bool lineOK = false;
      for (int i = 0; i < Items.Count; i++) {
        if (GetItemRectangle(i).Contains(clickedPt)) {
          lineOK = true;
        }
      }
      if (!lineOK) {
        return;
      }        
    }
    base.WndProc(ref m);
  }
}
公共类ListBoxEx:ListBox{
私有常量int WM_LBUTTONDOWN=0x201;
受保护的覆盖无效WndProc(参考消息m){
int lParam=m.lParam.ToInt32();
int wParam=m.wParam.ToInt32();
如果(m.Msg==WM_LBUTTONDOWN){
点击点PT=新点();
clickedPt.X=lParam&0x0000FFFF;
单击pt.Y=lParam>>16;
bool lineOK=false;
对于(int i=0;i

将我的答案张贴在thnx,以获得回复。在
MeasureItem
中,我只计算
e.ItemHeight
。如果我开始更改该值,行看起来就乱七八糟了。所有行的高度都相同。是否确实选中了该项,而不仅仅是在其周围绘制焦点框?
MessageBox.Show(listBox.SelectedIndex.ToString())MouseDown
中的code>返回最后一个项目(该项目也被选中)的索引。但第一个项目是在单击之前选择的。当我将该消息框放置在
SelectedIndexChanged
中并单击空白区域时-当我按下鼠标按钮时,最后一个项目会被绘制,当我松开鼠标按钮时,我会得到弹出窗口(带有最后一个项目的索引),然后它必须连接到绘图模式。一个具有普通DrawMode和表单上的一个列表框的快速测试应用程序不会这样做。所选项目保持选中状态,最后一个项目将获得焦点框(可通过将焦点设置为列表框上的另一个控件来“修复”)。单击以获取答复。在
MeasureItem
中,我只计算
e.ItemHeight
。如果我开始更改该值,行看起来就乱七八糟了。所有行的高度都相同。是否确实正在选择该项,而不仅仅是g