views:

990

answers:

3

Hi!

I'm developing a Windows Mobile app (Compact Framework 2.0 SP1) and this code it's generating me an error:



        public Image Imagen
        {
            get
            {
                return imagen;
            }
            set
            {
                imagen = value;
                this.Invalidate();
            }
        }

The code is called from a new thread. I've tried to solve using **InvokeRequired:


        public Image Imagen
        {
            get
            {
                return imagen;
            }
            set
            {
                imagen = value;
                if (this.InvokeRequired)
                    this.Invoke(this.Invalidate);
                else
                    this.Invalidate();
            }
        }

But the line this.Invoke(this.Invalidate); doesn't compile. How can I solve the problem? The first error is that you can interact with controls created on another thread.

Thank you!

A: 

The function Invoke expects an delegate, so you can use the built in Action delegate:

public Image Imagen
{
    get
    {
        return imagen;
    }
    set
    {
        imagen = value;
        if (this.InvokeRequired)
            this.Invoke(new Action(this.Invalidate));
        else
            this.Invalidate();
    }
}
Stormenet
It doesn't work. Action needs a T generic Type.
VansFannel
@VansFannel, System.Action (no-generics) was added in .Net 3.5
JaredPar
@Stormenet: I use Compact Framework 2.0 SP1
VansFannel
Sorry, missed that :)
Stormenet
+3  A: 

Try this.

Long winded version of why this is necessary. Instead of taking a specific Delegate type as a parameter, the Invoke method takes the type System.Delegate. This type does not providing typing for a strongly typed signature. It's the base delegate class and instead provides a common mechanism for invoking all delegates.

Unfortunately when passing a method name as a Delegate source in C# it must be passed to a specific delegate type. Otherwise C# doesn't know what type of delegate to create under the hood and unlike VB it won't generate anonymous delegate types. This is why you need a specific delegate type like MethodInvoker in order to call the function.

EDIT Manually defined MethodInvoker since it doesn't exist in the Compact Framework

public delegate void MethodInvoker();

public Image Imagen
{
    get { get return imagen; }
    set {
        imagen = value;
        if (this.InvokeRequired)
            this.Invoke(new MethodInvoker(this.Invalidate));
        else
            this.Invalidate();
    }
}
JaredPar
This Winform is for windows mobile so I use Compact Framework that it hasn't got methodinvoker.
VansFannel
@VansFannel, answer updated to deal with that
JaredPar
@JaredPar: Thank you!
VansFannel
A: 

My solution for Compact Framework 2.0 SP1 is this:

...

delegate void InvocadorMetodos();

...

        public Image Imagen
        {
            get
            {
                return imagen;
            }
            set
            {
                imagen = value;
                if (this.InvokeRequired)
                {
                    InvocadorMetodos invalida = Invalidar;
                    this.Invoke(invalida);
                }
                else
                    this.Invalidar();

            }
        }


Thank you!

VansFannel