4

there. I'm using C# .wpf, and I get this some code from C# source, but I can't use it. is there anything that I must change? or do?

 // Delegates to enable async calls for setting controls properties
    private delegate void SetTextCallback(System.Windows.Controls.TextBox control, string text);

    // Thread safe updating of control's text property
    private void SetText(System.Windows.Controls.TextBox control, string text)
    {
        if (control.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            Invoke(d, new object[] { control, text });
        }
        else
        {
            control.Text = text;
        }
    }

As above code, the error is in InvokeRequired and Invoke

the purpose is, I have a textbox which is content, will increment for each process.

here's the code for the textbox. SetText(currentIterationBox.Text = iteration.ToString());

is there anything wrong with the code?

thank you for any help

EDIT

// Delegates to enable async calls for setting controls properties
    private delegate void SetTextCallback(System.Windows.Controls.TextBox control, string text);

    // Thread safe updating of control's text property
    private void SetText(System.Windows.Controls.TextBox control, string text)
    {
        if (Dispatcher.CheckAccess())
        {
            control.Text = text;
        }
        else
        {
            SetTextCallback d = new SetTextCallback(SetText);
            Dispatcher.Invoke(d, new object[] { control, text });
        }
    }
Reza
  • 211
  • 6
  • 13
  • And exactly what is the error? – Ralph Shillington Apr 27 '11 at 11:40
  • have you get any error or you only assume that you have error in your code? – sikender Apr 27 '11 at 11:41
  • 1
    Any suggest? Error 2 'System.Windows.Controls.TextBox' does not contain a definition for 'InvokeRequired' and no extension method 'InvokeRequired' accepting a first argument of type 'System.Windows.Controls.TextBox' could be found (are you missing a using directive or an assembly reference?) – Reza Apr 27 '11 at 11:43

3 Answers3

10

You probably took that code from Windows Forms, where every Control has a Invoke method. In WPF you need to use the Dispatcher object, accessible through a Dispatcher property:

 if (control.Dispatcher.CheckAccess())
 {
     control.Text = text;
 }
 else
 {
     SetTextCallback d = new SetTextCallback(SetText);
     control.Dispatcher.Invoke(d, new object[] { control, text });
 }

Additionally, you're not calling SetText correctly. It takes two arguments, which in C# are separated with commas, not with equal signs:

SetText(currentIterationBox.Text, iteration.ToString());
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • it is still gets an error when I call it like this "SetText(currentIterationBox.Text = iteration.ToString());" – Reza Apr 27 '11 at 11:55
  • 3
    @Reza: **WHAT ERROR?** Why do you think they write the error descriptions? Because it's fun? Did you even read it? I bet it explains what's wrong. – R. Martinho Fernandes Apr 27 '11 at 11:59
  • sorry, here's the error "Error 2 No overload for method 'SetText' takes 1 argument" – Reza Apr 27 '11 at 12:03
6

In WPF you dont use Control.Invoke but Dispatcher.Invoke like this:

Dispatcher.Invoke((Action)delegate(){
  // your code
});

Use

Dispatcher.CheckAccess()

to check first.

Marino Šimić
  • 7,318
  • 1
  • 31
  • 61
  • i edit my code above, is it correct? because it's still get error when I call it like this SetText(currentIterationBox.Text = iteration.ToString()); – Reza Apr 27 '11 at 11:55
  • SetText is a method with two parameters, one is a texbox the other is a string. You should call it like this: SetText(currentIterationBox, iteration.ToString()); – Marino Šimić Apr 27 '11 at 12:03
3

In WPF using next construction:

if (control.Dispatcher.CheckAccess())
{
   ...
}
else
{
   control.Dispatcher.Invoke(...)
}
neebz
  • 11,465
  • 7
  • 47
  • 64
Nikita
  • 46
  • 4