WinForms 应用程序 UI 线程通过快速更新 TreeListView 来帮助实现

问题描述 投票:0回答:1

我目前有一个 WinForms 应用程序,在 TreeListView 中显示数据。数据是 CAN 消息,当前设置为一旦检测到新的 CAN 消息就更新树列表视图。主导航是一个选项卡控件,可在不同功能和传入 CAN 消息的处理之间切换。

从任何选项卡切换到我的树列表视图所在的选项卡时就会出现问题。每当 CAN 消息以 10 毫秒左右的间隔开始传入时,就会出现问题。树列表视图按照我的意愿进行绘制和更新,但所有其他控件根本不绘制,更不用说交互了。我使用选项卡控件打开的上一页也仍然显示,因此树列表视图被绘制在旧选项卡页上,没有绘制任何其他控件,并且旧选项卡页仍然显示,尽管是非交互式的。

我尝试这样做,以便每当您切换到包含 CAN 消息的选项卡页时,它都会停止处理 CAN 消息一小段时间,以便 UI 线程至少可以绘制其他控件,并且它确实有效。其他控件确实进行了绘制,但仍然没有交互性。我无法单击任何按钮或选择其他控件上的任何内容。

目前的设置是使用另一个后台线程来检查新消息,并在检测到消息时触发事件来处理该消息。然后数据处理在另一个线程上完成,最后将数据推送到 UI 线程来更新 UI。

几周前,我使用的是普通的ListView,然后这些错误都没有发生,直到现在当我切换到treelistview时才开始发生这种情况。

以下是消息处理中的一些代码: ` 字符串 sFullPGN = data.completePGN;

if (sTxtBoxPGNDisplay == sFullPGN)
    txtBoxTxInfo.Text = getRxTooltip(ref data);

if (CAN_PGNS.Contains(sFullPGN))
{
    int index = GetAdapterIndex(sFullPGN);
    if (index != -1)
    {

        Adapters[index].UpdateAdapterData(data);

        if (Adapters[index].Children != null) // Does the PGN contain any signals?
        foreach(CANAdapter signal in Adapters[index].Children)
        {
            signal.UpdateChild(data);
        }
        // RefreshObject gives an error if a filter is applied, complains about index error since ObjectListView uses it own internal display list 
        // which is changed when a filter is applied. The All objects list's index is then taken directly instead of being adapted to the 
        // display list's matching showing index. This is all internal code of the ObjectListView and cannot be changed by us.
        // See line btnCHfilter_click below.

        //tlvCANIn.RefreshObject(Adapters[index]);
        try { tlvCANIn.RefreshObject(Adapters[index]); } catch {}   
    }
}
else
{
    CANAdapter newAdapter = new CANAdapter(sFullPGN);
    CanMessageInfo newMessage = new CanMessageInfo();
   
    newMessage = CANMessagesInfo.GetMessage(data.PGN_RBDP);
    newAdapter.UpdateAdapterData(data);
    if (newMessage != null)
    {
        newAdapter.comment = newMessage.name + " " + newMessage.comment;
        if (newMessage.signals.Count > 0)
        {
            newAdapter.HasSPNs = true;
            newAdapter.InitialiseChildren(newMessage.signals);
        }
        else
        {
            newAdapter.HasSPNs = false;
        }
    }
    Adapters.Add(newAdapter);
    CAN_PGNS.Add(sFullPGN);
}

}`

c# winforms ui-thread objectlistview treelistview
1个回答
0
投票

我发现的最佳解决方案是限制 UI 更新速率,但仍然处理带有计时器更新的 CAN 消息。我将所有需要更新的对象添加到列表中,并在计时器回调中使用

tlvMyTreeListView.RefreshObject(objectToRefresh)
更新该列表

© www.soinside.com 2019 - 2024. All rights reserved.