Cannot set AllowDrop from a callback

  • Thread starter Thread starter johnxsun
  • Start date Start date
J

johnxsun

Hello,

I am having a problem with set AllowDrop from a callback function for
any types of control boxes, ie. ListView. The following is the example
code that creates the problem. The listView1.AllowDrop never get set
and there is no error or warning as well. Also, if there is any code
after the line "listView1.AllowDrop = false;" will never get excuted.
It seems only happen to the AllowDrop property, others, such as color,
Enabled, are fine.

I appreciate if anybody can help me out here.

Thanks.
John
-------------------------------------------------------------------------------------------
public delegate void ipcEventCallback();
public static ipcEventCallback ipcEventHandler;

private void Form1_Load(object sender, System.EventArgs e)
{
// Init ipcEventCallback interface
ipcEventHandler = new ipcEventCallback(IpcEventHandler);
}

void IpcEventHandler()
{
listView1.AllowDrop = false;
}

private void button1_Click(object sender, System.EventArgs e)
{
ipcEventHandler.BeginInvoke(null, null);
}
-------------------------------------------------------------------------------------------
 
Setting the AllowDrop requires that the thread enters a single-threaded
apartment when you call BeginInvoke your thread will enter a multi-threaded
apartment. Anyways I find it strange that you don't get an exception...

Gabriel Lozano-Morán
Real Software
 
Forgot to mention that you need to call the IpcEventHandler() synchronously
with Invoke() instead of asynchronously with BeginInvoke().

Gabriel Lozano-Morán
Real Software
 
Thanks for the help!

So, For this example, I should do something like
"this.Invoke(ipcEventHandler, null);" right?
And this will block the GUI thread until it's finished, right?

But why is this? Why only AllowDrop but not others (I can set any other
properties from the BeginInvoke())? Would you please point me to some
document that explains this?

Thanks again.
John
 
The AllowDrop property is a special case because it will register the window
as a client for drag-and-drop operations. OLE needs to be enabled on the
thread and is therefore initialized and to make sure that the operation is
thread-safe Microsoft has added a check to verify that the current thread is
running in a single-threaded apartment.

I have looked on the MDSN trying to find an article for you that somehow
explains it:
http://msdn.microsoft.com/library/d...html/9a13e7a0-f2e2-466b-98f5-38d5972fa391.asp

Gabriel Lozano-Morán
Real Software

Thanks for the help!

So, For this example, I should do something like
"this.Invoke(ipcEventHandler, null);" right?
And this will block the GUI thread until it's finished, right?

But why is this? Why only AllowDrop but not others (I can set any other
properties from the BeginInvoke())? Would you please point me to some
document that explains this?

Thanks again.
John
 
Hi Gabriel,

Thanks for the info. Please allow me to ask you one more question.

So, what is the right way to modify the AllowDrop field from another
thread?
I just find out that the invoke cannot be called from another thread as
well.

The code I initially posted is not the one I am using actually but it
generates the same problem. I have a GUI and a background running
thread that needs to change certain GUI things. I let the GUI provide
some delegates so the background thread can use them to operate on the
GUI when it's needed but not block the GUI. Do you think it's correct
way of doing this?

Thanks,
John
 
For example:

private delegate void SetAllowDropHandler(Control control, bool value);

private void SetAllowDrop(Control control, bool value)
{
if (control.InvokeRequired)
{
control.Invoke(new SetAllowDropHandler(SetAllowDrop), new object[]
{ control, value} );
}
else
{
control.AllowDrop = value;
}
}


Gabriel Lozano-Morán
MCSD .NET
Real Software
http://www.realsoftware.be
 
Back
Top