[help] c# listbox databinding not updating

07/29/2009 02:50 clintonselke#1
Hi guys,

I'm new to c#... my first time, and hopefully not he last. :D

Just having trouble with listbox data-binding atm. For reasons I don't know, when changes are made to the data which the listbox is bounded to, the changes are not reflected inside the listbox.

The following is some of the code i'm using.

Firstly the intialisation and the bounding of the data to the listbox.
PHP Code:
        public MainForm()
        {
            
//
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            
InitializeComponent();
            
            
//
            // TODO: Add constructor code after the InitializeComponent() call.
            //
            
conquerProcesses = new ArrayList();
            
clientsListBox.DataSource conquerProcesses;
            
clientsListBox.DisplayMember "Name";
            
clientsListBox.ValueMember "Name";
        } 
As ya can see, i'm using the DataSource property to bound it to my list of running conquer online processes.

And this process list is updated by a timer object which triggers the following code 10 times per second.

PHP Code:
        void Timer1Tick(object senderEventArgs e)
        {
            
Process[] processList Process.GetProcessesByName("Conquer");
            foreach (
Process process in processList)
            {
                
//if (!clientsListBox.Items.Contains(process))
                //    clientsListBox.Items.Add(process);
                
bool has false;
                foreach (
CConquerProcess process2 in conquerProcesses)
                {
                    if (
process2.id == process.Id)
                    {
                        
has true;
                        break;
                    }
                }
                if (!
has)
                {
                    
conquerProcesses.Add(new CConquerProcess(process));
                }
            }
            
ArrayList removeList = new ArrayList();
            foreach (
CConquerProcess process2 in conquerProcesses)
            {
                
bool has false;
                foreach (
Process process in processList)
                {
                    if (
process2.id == process.Id)
                    {
                        
has true;
                        break;
                    }
                }
                if (!
has)
                {
                    
removeList.Add(process2);
                }
            }
            foreach (
CConquerProcess process in removeList)
                
conquerProcesses.Remove(process);
            foreach (
CConquerProcess process in conquerProcesses)
                
process.Update();
        }
    } 
and the CConquerProcess::Update() method updates the names of the characters from the running list of the processes by using getters/setters for the "Name" property of which the listbox is bounded to.

This update of the "Name" property only happens if there has been a change in character name (the person DCs and logs in another character), and the Update() method is called for every conquer process 10 times per second.

PHP Code:
    public class CConquerProcess
    
{
        public 
int    id;
        public 
IntPtr handle;
        public 
IntPtr playerBase;
        public 
string lastName "";
        
        public 
CConquerProcess(Process process)
        {
            
id process.Id;
            
handle MainForm.OpenProcess(MainForm.PROCESS_ALL_ACCESSfalseid);
            
int tmp;
            
byte[] bytes = new byte[4];
            
MainForm.ReadProcessMemory(handle, (IntPtr)0x00691CA0bytes4out tmp);
            
playerBase = (IntPtr)(bytes[0] + ((int)bytes[1] << 8) + ((int)bytes[2] << 16) + ((int)bytes[3] << 24));
            
//MessageBox.Show(id.ToString(),"k");
            //Debug.WriteLine(id + " constructed.");
            
lastName Name;
        }
        
        ~
CConquerProcess()
        {
            
MainForm.CloseHandle(handle);
        }
        
        public 
void Update()
        {
            
int tmp;
            
byte[] bytes = new byte[4];
            
MainForm.ReadProcessMemory(handle, (IntPtr)((int)playerBase 0x10C), bytes4out tmp);
            
IntPtr nameAddr = (IntPtr)(bytes[0] + ((int)bytes[1] << 8) + ((int)bytes[2] << 16) + ((int)bytes[3] << 24));
            
MainForm.ReadProcessMemory(handle, (IntPtr)((int)playerBase 0x110), bytes4out tmp);
            
IntPtr nameAddr2 = (IntPtr)(bytes[0] + ((int)bytes[1] << 8) + ((int)bytes[2] << 16) + ((int)bytes[3] << 24));
            
int length = ((int)nameAddr2 - (int)nameAddr);
            
bytes = new byte[length];
            
MainForm.ReadProcessMemory(handlenameAddrbyteslengthout tmp);
            
string name "";
            for (
int i 0length; ++i)
                
name += (char)bytes[i];
            if (
lastName.CompareTo(name) != 0)
            {
                
Name name;
            }
        }
        
        public 
string Name
        
{
            
get
            
{
                return 
lastName;
            }
            
set
            
{
                
lastName value;
            }
        }            
    } 
when i check this inside Debugger.WriteLine() it seems to work fine... but for some reason the listbox is not updating when its bounded data changes. Which seems to work for others on google.

Any Ideas?

Thx in advance.
07/29/2009 03:44 high7#2
Try using ListBox.Refresh(). The reason it is not updating is because the ListBox has no way of telling when the databinding has an item added.
07/29/2009 06:05 clintonselke#3
Quote:
Originally Posted by high7 View Post
Try using ListBox.Refresh(). The reason it is not updating is because the ListBox has no way of telling when the databinding has an item added.
Thanks high6, working now.

I chucked in the following in the end of my timer function.
PHP Code:
            clientsListBox.DataSource conquerProcesses;
            
clientsListBox.Refresh(); 
Which redraws all the elements all the time, which i think kinda defeats the purpose of data binding. But oh well.
07/29/2009 17:20 unknownone#4
You're supposed to derive a class from ListBox and override the RefreshItems() method to sync the list with your data source.