【问题标题】:C# Order a list of labels by location on screenC# 按屏幕上的位置排序标签列表
【发布时间】:2014-03-20 10:16:11
【问题描述】:

如何按标签在屏幕上的位置排列标签列表? 我的标签在屏幕上移动,但只在 X 轴上移动,这是我拥有的代码,但我注意到它不起作用。

 labels.OrderBy(x => x.Location.X);

提前谢谢你!

编辑:这就是我测试它是否有效的方式......

 private void actualizarPosicoes() {

        labels.OrderBy(x => x.Location.X);

        MessageBox.Show(labels.First.Value.Text.ToString());


    }

但我想在从屏幕上删除标签时使用它,但首先我必须让 OrderBy 工作。

 private void reorder(Label lb) {

        labels.OrderBy(x => x.Location.X);
        var it = labels.GetEnumerator();

        var node = it.Current;
        while (it.MoveNext())
        {
            var nextNode = it.MoveNext();
            if (nextNode != null)
            {
                if (nextNode.Equals(lb))
                {
                    nextNode = it.MoveNext();
                    it.Current.Location = new Point(node.Right, 0);
                }
            }
            node = it.Current;

        }


    }

我有一个名为标签的全局链表:

private LinkedList<Label> labels;

【问题讨论】:

  • 你怎么知道它不起作用?
  • 它的哪一部分不起作用?他们都有相同的父控件吗?还是它们属于不同的控件?您如何在排序之前获得初始列表?
  • 请交更多你的代码,根本不够继续。我唯一能猜到的是您需要将labels 的值重新分配为OrderBy 的结果。即labels = labels.OrderBy(x =&gt; x.Location.X); 但在您提供更多上下文之前,这只是一个猜测。
  • 它返回带有有序列表的新Enumerable,你想做什么?
  • @JoãoSilva 您试图将所有标签对齐成一行,中间没有空格?

标签: c# winforms list location


【解决方案1】:

我建议您使用FlowLayoutPanel 作为标签的容器。删除任何标签会自动重新排列其他标签。

这里是示例 - 假设您有 labelsFlowLayoutPanel 托管标签和 addLabelButton 添加标签:

private void addLabelButton_Click(object sender, EventArgs e)
{
    Label label = new Label();
    label.Text = DateTime.Now.ToLongTimeString();
    label.DoubleClick += label_DoubleClick;
    labelsFlowLayoutPanel.Controls.Add(label);
}

void label_DoubleClick(object sender, EventArgs e)
{
    Label label = (Label)sender;
    labelsFlowLayoutPanel.Controls.Remove(label);
    label.DoubleClick -= label_DoubleClick;
}

每次单击addLabelButton 时都会创建新标签并将其插入到其他标签的右侧。双击任何标签将删除它并重新排列其他标签。

更多信息 - Windows Forms Controls Lesson 5: How to use the FlowLayout Panel

【讨论】:

  • 我之前有 FlowLayoutPanel,但它没有按我的需要工作,所以我必须创建自己的自定义面板...
【解决方案2】:

不提供任何更好的方法建议,直接回答问题,你的代码问题如下:

不修改实例的OrderBy方法被调用,它将返回一个新的IOrderedEnumerable&lt;TSource&gt;,其中TSource是对象的类型,例如Label。这意味着您的代码应如下所示:

labels = labels.OrderBy(x => x.Location.X);

根据labels 的对象类型,您可能需要将其转换为List,如下所示:

labels = labels.OrderBy(x => x.Location.X).ToList();

编辑:我刚刚意识到您正在使用LinkedList,我建议将其更改为private List&lt;Label&gt; labels;

【讨论】:

    【解决方案3】:

    我终于做到了! 有需要的人有答案...

    private void reorder() {
    
    var it2 = labels.OrderBy(x => x.Location.X);
    Label orderLb = it2.ElementAt(0);
    
    for (int i = 1; i < labels.Count; i++)
    {
        it2.ElementAt(i).Location = new Point(orderLb.Right, 0);
        orderLb = it2.ElementAt(i);
    }
    

    感谢大家的帮助,非常感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 2019-06-18
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      相关资源
      最近更新 更多