ListBox的Refresh方法不会触发DrawItem属性的事件处理程序

时间:2019-04-24 00:15:51

标签: c# forms delegates thread-safety eventhandler

我试图创建一个绑定到列表的listBox,当它检查列表中的每个元素或对列表的每个元素执行某些处理时,它将更改列表框控件上该项目的颜色。 列表框第一次加载时,它将显示列表中的所有元素,并经过我的listbox_Drawitem事件处理程序,该事件处理程序接收DrawItemEventArgs事件。 但是,当我想刷新列表框以使用更新的状态或颜色重新绘制项目时,它永远不会通过listbox_DrawItem事件处理程序。

我尝试单独使用刷新方法没有成功。 我尝试将list.Datasource设置为null,然后将list.refresh设置为null,这会擦除列表框中的所有内容,然后将数据源再次设置为我的列表并刷新,但是什么也没有发生。

我正在使用两个线程,当我从UI表单以外的另一个线程编辑控件时,我通过委托来进行操作以避免跨线程错误。到目前为止,它一直在工作,除了DrawItem处理程序应该通过在我的委托中的safeRefreshAllMethod中的刷新重绘我的控件来触发。

这是我的UI表单中的代码:


    public partial class Form1 : Form
    {

        public delegate void SafeRefresh();
        public SafeRefresh myDelegate;
        private Form1 currentForm;
        Thread scriptThread;

        public Form1()
        {
            InitializeComponent();
            currentForm = this;
            myDelegate = new SafeRefresh(SafeRefreshAllMethod);

        }
        private async void button_script_Click(object sender, EventArgs e)
        {
            scriptThread = new Thread( () => SomeClass.RunScript(currentForm));
            scriptThread.Start();
        }

        public void SafeRefreshAllMethod()
        {

            listBox.DataSource = null;
            listBox.Refresh();
            listBox.DataSource = Global.ListAllItems; 
            listBox.Refresh();
        }


        public void listBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            Brush myBrush;
            if (Global.ListItemsDisconnected.Contains(Global.ListAllItems[e.Index] ))
            {
                myBrush = Brushes.Gray;
            }
            else if (Global.ListItemsConnected.Contains(Global.ListAllItems[e.Index]))
            {
                myBrush = Brushes.Green;
            }
            else
            {
                myBrush = Brushes.Black;
            }

            e.DrawBackground();
            e.Graphics.DrawString(listBox.Items[e.Index].ToString(), listBox.Font, myBrush, e.Bounds);
        }

    }

这是新线程以表单的形式执行的代码,该代码调用委托以刷新列表框控件:

class SomeClass {
public static void  RunScript(Form1 theForm)
        {
            theForm.Invoke(theForm.myDelegate);

            foreach (string item in Global.ListAllItems)
            {

                //some code that works with the items on list
                //if disconnected : adds to Global.ListItemsDisconnected
                //if connected: adds it to Global.ListItemsConnected

                theForm.Invoke(theForm.myDelegate);


            }
        }
}

我想知道是否有人知道为什么线程第一次调用控件绘制列表中的所有项时会触发listBox_DrawItem。但是,当我尝试刷新并重绘具有不同颜色的列表时,处理程序将永远不会被调用。

1 个答案:

答案 0 :(得分:0)

查看设计器,尝试将 DrawMode 属性更改为 OwnerDrawFixed

ListBox DrawMode Example