Метод Refresh для ListBox не будет вызывать обработчик события для свойства DrawItem - PullRequest
0 голосов
/ 24 апреля 2019

Я пытаюсь создать listBox, который привязан к списку, и когда он проверяет или выполняет определенный процесс с каждым элементом списка, он изменит цвет этого элемента в элементе управления listbox. При первой загрузке списка он отображает все элементы из списка и проходит через мой обработчик события listbox_Drawitem, который получает событие DrawItemEventArgs. Но когда я хочу обновить список, чтобы перерисовать элементы с обновленным состоянием или цветом, он никогда не проходит через обработчик событий listbox_DrawItem.

Я попытался использовать метод обновления безуспешно. Я попытался установить для list.Datasource значение null, а затем list.refresh, который стирает все в списке, а затем снова установить источник данных в мой список и обновить, но ничего не происходит.

Я работаю с двумя потоками, и когда я редактирую свои элементы управления из другого потока, отличного от формы пользовательского интерфейса, я делаю это через делегатов, чтобы избежать ошибок между потоками. До сих пор это работало, за исключением обработчика DrawItem, который должен запускаться при перерисовке моего элемента управления обновлением внутри safeRefreshAllMethod в моем делегате.

Это код из моей формы пользовательского интерфейса:


    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 голосов
/ 24 апреля 2019

Просмотрите конструктор и попробуйте изменить свойство DrawMode на OwnerDrawFixed .

Пример ListBox DrawMode

...