【问题标题】:c# listbox get displayed range of indicesc# listbox获取显示的索引范围
【发布时间】:2011-11-04 11:35:57
【问题描述】:

我有一个列表框,我想显示一个标签:

在 ZZZ 的 XXX 到 XYY 之间滚动。

我该怎么做,因为使用 SelectedIndex 没有用,因为我希望即使没有选择任何内容也能更新标签。 (滚动也不会选择项目)。

更新: 例如,我的列表框中有 200 个项目。由于列表框的高度,在任何时候我都只能显示 10 个项目。所以标签应该是:

显示 200 项中的第 1 到 10 项

显示 200 项中的第 5 至 15 项

但是我必须考虑到可能没有选择任何索引,因为我可以简单地滚动而不选择任何东西。

【问题讨论】:

标签: c# winforms


【解决方案1】:

您可以使用listbox.TopIndex 获取顶部索引值,使用listbox.Items.Count 获取计数但我看不到任何方法来获取底部项目,而无需从listbox.GetItemHeight()listbox.ClientSize.Height 的结果中计算它:

int visibleCount = listBox1.ClientSize.Height / listBox1.ItemHeight;
this.Text = string.Format("{0:d} to {1:d} of {2:d}", listBox1.TopIndex + 1, listBox1.TopIndex + visibleCount, listBox1.Items.Count);

这可以在计时器上完成,因为我没有看到滚动事件。

【讨论】:

  • 啊,是的,我并不是说其他​​方法不起作用,但这提供了最快的解决方案!谢谢!
【解决方案2】:

只需使用 ListBox 的 Scroll 事件。哦等等,一个都没有。您可以添加一个:

public class ListBoxEx : ListBox {
  public event EventHandler Scrolling;

  private const int WM_VSCROLL = 0x0115;

  private void OnScrolling() {
    if (Scrolling != null)
      Scrolling(this, new EventArgs());
  }

  protected override void WndProc(ref Message m) {
    base.WndProc(ref m);
    if (m.Msg == WM_VSCROLL)
      OnScrolling();
  }
}

一旦你使用它,它只是数学(根据需要重构):

private void listBoxEx1_Resize(object sender, EventArgs e) {
  DisplayRange();
}

private void listBoxEx1_Scrolling(object sender, EventArgs e) {
  DisplayRange();
}

private void DisplayRange() {
  int numFrom = listBoxEx1.TopIndex + 1;
  int numTo = numFrom + (listBoxEx1.ClientSize.Height / listBoxEx1.ItemHeight) - 1;
  this.Text = numFrom.ToString() + " to " + numTo.ToString();
}

如果是IntegralHeight=False,那么您可能需要使用范围编号来确定是否包含部分行。

如果使用DrawMode=OwnerDrawVariable,则需要使用 MeasureItem 事件遍历可见行。

【讨论】:

    【解决方案3】:

    这是抽奖,你可以这样做

        private int min = 1000;
        private int max = 0;
        private void comboBox3_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (min >= e.Index) min = e.Index+1;
            if (max <= e.Index) max = e.Index+1;
    
            float size = 10;
            System.Drawing.Font myFont;
            FontFamily family = FontFamily.GenericSansSerif; 
    
            System.Drawing.Color animalColor = System.Drawing.Color.Black;
            e.DrawBackground();
            Rectangle rectangle = new Rectangle(2, e.Bounds.Top + 2,
                    e.Bounds.Height, e.Bounds.Height - 4);
            e.Graphics.FillRectangle(new SolidBrush(animalColor), rectangle);
            myFont = new Font(family, size, FontStyle.Bold);
            e.Graphics.DrawString(comboBox3.Items[e.Index].ToString(), myFont, System.Drawing.Brushes.Black, new RectangleF(e.Bounds.X + rectangle.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
    
            e.DrawFocusRectangle();
    
            label1.Text = String.Format("Values between {0} and {1}",min,max);
        }
    

    您必须找到正确的事件来重置最小值和最大值以及重新绘制组合框的正确值。

    此代码不是解决方案,它只是您如何实现您的要求的一个想法。

    最好的问候。

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 1970-01-01
      • 2021-06-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多