UI Update Error

If I call to update a
private static UIElement Elements()
{
var panel = new Panel();

        txt3 = new Text(font, "SV")
        {
            ForeColor = Colors.White,
            HorizontalAlignment = HorizontalAlignment.Right,
        };

        txt3.SetMargin(50);
        panel.Children.Add(txt3);

}
If I call the below code from a button click, it works
private static void Button_Click(object sender, RoutedEventArgs e)
{

}
, but If I call from another class it give the below exception

    public static void TempSV_Update(String t)
    {
        Program.DB_Print("Temp SV Update");

        txt3_temp = t;

        txt3.TextContent = txt3_temp;
        txt3.Invalidate();
    }

Exception
image

Call stack
image

All UI elements are changed and updated from within the UI dispatcher:

User Interface (ghielectronics.com)

If want call from any function not in UI dispatcher thread, use below:

private void CallAnyWhere() => Application.Current.Dispatcher.Invoke(TimeSpan.FromMilliseconds(timeut), _ => {

           uiElement.Text = ..... // change

            return null;
        }, null);

Thanks, works good now :slight_smile:

1 Like
		const byte NUM_BUT = 3;
		Button[] button = new Button[NUM_BUT];
		for (Int16 i = 0; i < NUM_BUT; i++)
        {
			button[i] = new Button()
			{
				Child = txt,
				Width = 200,
				Height = 40,
			};

			button[i].Click += Button_Click( i);
			panel.Children.Add(button[i]);
		}

is it possible to pass a variable to the call back function.

No, but …

Method 1 : you can use the ‘sender’ arg of the button click method signature and then an IndexOf() operator to find the control within the array. Or, just cast ‘sender’ to type Button and access it directly.

Method 2 : If you need something other than a ref to the Button, then use IndexOf to get the index, and then use that as the index into some parallel array containing the other information you need.

Method 3 : Create a subclass of Button and put additional information in there, and then cast ‘sender’ to your new subclass type.

So, no, you can’t change the signature of the callback, but there are multiple ways to accomplish the same thing.

1 Like
    private static void TClick(object sender, RoutedEventArgs e)
    {
        if (e.RoutedEvent.Name == "TouchDownEvent")
        {
                sender.IndexOf??
        }
    }

Would you please provide me a example of how to use IndexOf
I could not figure out how to use Method 2

Ok, so taking your two code snippets, I whipped this up quickly… It’s not meant to be cut-and-pasted into your program, but it illustrates the approach…

public class SomeClass 
{
    const byte NUM_BUT = 3;

    Button[] buttons = new Button[NUM_BUT];

    // The ButtonData class is information that you want to associate with
    //   each button. What's in this class is up to you to define.
    // The type of this array is unimportant. It's just a parallel array to buttons[]
    //   What you define this to be is application-specific.
    ButtonData[] buttonData = new ButtonData[NUM_BUT];

    public void Initialize()
    {
        for (Int16 i = 0; i < NUM_BUT; i++)
        {
            buttons[i] = new Button()
            {
                Child = txt,
                Width = 200,
                Height = 40,
            };

            //TODO: Initialize buttonData[i] with app-specific data

            this.buttons[i].Click += this.Button_Click;
            panel.Children.Add(this.buttons[i]);
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //COMMENT: In general, it's better to use TouchUpEvent which better
        //   aligns with user expectations and experiences on other touch devices
        if (e.RoutedEvent.Name == "TouchDownEvent")
        {
            var idx = this.buttons.IndexOf(sender);
            if (idx > -1 && idx < NUM_BUT)
            {
                var data = this.buttonData[idx];
                //TODO: do something with 'data'
            }
        }
    }
}

Thank you very much, this works great

2 Likes