首页 > 解决方案 > 如何将对自定义事件或方法的重复调用减少到一个?

问题描述

如果我的事件/方法在第一次调用完成之前被调用了两次,它应该像只调用一次一样做出反应。超过 1 个连续调用应减少为 1 个。

我相信这就是Control.InvalidateWinforms 中的方法所做的。

我有一个容器控件(基于FlowLayoutPanel)。这些控件有一个 ID 号,在删除或添加其中一些控件时必须更新该 ID 号(它们应该具有从 开始的连续 ID 1)。更新 ID 的方法RefreshDisplay可能会被调用多次,直到执行返回到主消息循环。

更新1:

我认为该Invalidate方法减少了对它的多次连续调用。文档说:

使控件的指定区域无效(将其添加到控件的更新区域,这是将在下一次绘制操作中重新绘制的区域),并导致向控件发送绘制消息。

就我而言,它是一种方法,但我也想过使用事件处理程序将其设为事件。

在以下情况下调用该RefreshDisplay方法:

  1. 创建或删除一个项目(例如,当删除一行或多行 aDataGridView时);
  2. 集合中的一个项目被移动到同一集合中的另一个位置;
  3. 集合中的项目组被更改(例如重命名或删除组);
  4. 当为集合创建视图时(例如在程序开始时);
  5. 当视图的子级设置为不可见或可见时(可见性是子级模型的一部分)。

RefreshDisplay方法(我希望将其连续调用减少到 1)是通过以下方式实现的接口的一部分:

1.

public void RefreshDisplay()
{
    SuspendLayout();
    int i = 0;
    foreach (ClockDataGridViewRow r in Rows)
    {
        if (r.IsNewRow)
        {
            continue;
        }
        r.HeaderCell.Value = (i + 1).ToString();
        if (!r.MyClockData.FilteredOut)
        {
            ++i;
        }
    }
    ForceUpdateZoomFactor(ZoomFactor);
    ResumeLayout(true);
}

2.

public void RefreshDisplay()
{
    SuspendLayout();
    int i = 0;
    foreach (ClockData td in MyDataFile.ClockCollection.ClocksData)
    {
        foreach (IClockView tv in td.MyTimerViews)
        {
            if (tv is ClockControl tc &&
                tc.GetTimersView() == this)
            {
                tc.SetTagText((i + 1).ToString());
            }
        }
        if (!td.FilteredOut)
        {
            ++i;
        }
    }
    ResumeLayout(true);
}

3.

public void RefreshDisplay()
{
    MyListView.Items.Clear();
    UpdateListViewImageLists(ZoomPercent);
    ListViewItem it = MyListView.Items.Add("All");
    it.Tag = new Filter()
    {
        ShowActive = true,
        ShowInactive = true,
        ShowTimers = true,
        ShowAlarms = true
    };
    it.ImageIndex = 1;
    ListViewItem itActive = MyListView.Items.Add("Active");
    itActive.Tag = new Filter()
    {
        ShowActive = true,
        ShowInactive = false,
        ShowTimers = true,
        ShowAlarms = true
    };
    itActive.ImageIndex = 2;
    ListViewItem itInactive = MyListView.Items.Add("Inactive");
    itInactive.Tag = new Filter()
    {
        ShowActive = false,
        ShowInactive = true,
        ShowTimers = true,
        ShowAlarms = true
    };
    itInactive.ImageIndex = 3;
    ListViewItem itTimers = MyListView.Items.Add("Timers");
    itTimers.Tag = new Filter()
    {
        ShowActive = true,
        ShowInactive = true,
        ShowTimers = true,
        ShowAlarms = false
    };
    itTimers.ImageIndex = 4;
    ListViewItem itAlarms = MyListView.Items.Add("Alarms");
    itAlarms.Tag = new Filter()
    {
        ShowActive = true,
        ShowInactive = true,
        ShowTimers = false,
        ShowAlarms = true
    };
    itAlarms.ImageIndex = 5;
    int gi = 0;
    foreach (string g in MyDataFile.ClockCollection.Groups)
    {
        ListViewItem item = MyListView.Items.Add(g);
        item.Tag = new Filter()
        {
            ShowActive = true,
            ShowInactive = true,
            ShowAlarms = true,
            ShowTimers = true
        };
        (item.Tag as Filter).GroupIndices.Add(gi);
        Image ico;
        if (MyDataFile.ClockCollection.Groups.Icons.ContainsKey(g))
        {
            // possibly null:
            ico = MyDataFile.ClockCollection.Groups.Icons[g];
        }
        else
        {
            ico = null;
        }
        MyListView.SmallImageList.Images.Add(
            ico ?? new Bitmap(1, 1));
        MyListView.LargeImageList.Images.Add(
            ico ?? new Bitmap(1, 1));
        if (ico != null)
        {
            item.ImageIndex = item.Index + 5;
        }
        else
        {
            item.ImageIndex = 0;
        }
        ++gi;
    }
}

标签: c#winforms

解决方案


推荐阅读