Main Site Documentation

Presentation - Updating a window (Main window)


#1

Hello,

I am wondering, what would be the best idea for updating a window? I have a window with several bitmaps.

These bitmaps represent on or off state of objects. Once a object switches state, I would like to update the image too.

This window is the main window, so no window that can be opened by button.

Once the window is created, the bitmaps cannot change, since the window does not get closed. The only thing happening is that another window gets opened on top of it. (Visible = true)

How do I run some sort of update window function to update my bitmaps on the main window?

Thank you!


#2

Something like an “update thread”, running in the background and monitoring some variables ?


#3

Have checked the official GHI demo?

…did I mention that I personally HATE WPF in NETMF?


#4

Yes I did Gus. You make use of the demogridpanel.
I am using the same screen build up (titlebar, yours) and stackpanel with the content.

There are several “buttons” (bitmaps) which represent things like a USB Joystick connected.

On main window startup this happens:


joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);

But I do not know a way to update this. Because the main windows stays active and other windows are getting laid over it.

How to update this button to:


joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);

So in fact “updating” the main window (or the buttons on it)?


#5

You need to store a reference to the UIElement somewhere in code, otherwise you have no way of accessing it later on.


#6

What would be the best way to do this? Do you have a example of this?
Thanks!


#7

Can you post more code?


#8

Having not checked, does WPF in NetMF have bindings? If it does, just create a MVVM pattern window and change the object in your view model.


#9

public class Main : Window
    {
        private static StackPanel stack_Title;
        private static StackPanel stack_Content;
        private static StackPanel stack_Window;

        private static Bitmap settingsButton;
        private static Bitmap joystickButton;

        private Program _Program;

        private static USBH_Mouse mouse;
        private static USBH_Mouse keyboard;
        private static USBH_Mouse joystick;

        public Main(Program program)
        {
            _Program = program;

            // Create a new stack panel, set margins, and bind it to the window
            stack_Content = new StackPanel(Orientation.Horizontal);
            stack_Title = new StackPanel(Orientation.Horizontal);
            stack_Window = new StackPanel(Orientation.Vertical);
            this.Child = stack_Window;

            // Titlebar
            TitleBar titleBar = new TitleBar("Foekie's Desktop");
            titleBar.HorizontalAlignment = HorizontalAlignment.Left;
            stack_Title.Children.Add(titleBar);

            // Create a new window and apply the necessary properties
            this.Height = SystemMetrics.ScreenHeight;
            this.Width = SystemMetrics.ScreenWidth;
            this.Background = new ImageBrush(Resources.GetBitmap(Resources.BitmapResources.background)) { Stretch = Stretch.None };

//add settings button
            settingsButton = Resources.GetBitmap(Resources.BitmapResources.icon_Settings);
            settingsButton.MakeTransparent(Color.Black);
            Image image = new Image(settingsButton);
            image.HorizontalAlignment = HorizontalAlignment.Left;
            image.SetMargin(10, 10, 0, 0);
            image.TouchDown += openSettings;
            stack_Content.Children.Add(image);

//add joystick button
            joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
            joystickButton.MakeTransparent(Color.Black);
            Image image2 = new Image(joystickButton);
            image2.HorizontalAlignment = HorizontalAlignment.Left;
            image2.SetMargin(10, 10, 0, 0);
            stack_Content.Children.Add(image2);

//add title and content to the window stack.
            stack_Window.Children.Add(stack_Title);
            stack_Window.Children.Add(stack_Content);
        }

        static void updateWindow()
        {
            //Would it be possible with a method?
        }

        public void openSettings(object sender, TouchEventArgs args)
        {
            new Settings(_Program);
        }

So this is the basic code. I have stripped out some junk, otherwise it would be way too big.
I would like to update the joystickButton object with a new image.


joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);

How to?
Thanks for your help so far! :slight_smile:


#10

You should just be able to change joystickbutton elsewhere in your code since it is at a class level.


#11

Ok, so i fixed it for you :slight_smile:

I refactored some of your names to match Microsoft’s coding best practices :wink:

Basically, you were storing the image that you use on the control as a field in your class, rather than the control. You want to re-use the control just changing the image, so i did that.

It also looked like you were wanting some sort of singleton pattern class so you just have one instance of MainWindow which you can reference from anywhere. Now you can just use MainWindow.Instance.whatever().


public class MainWindow : Window
    {
        public static MainWindow Instance { get; private set; }

        StackPanel stackTitle;
        StackPanel stackContent;
        StackPanel stackWindow;

        Image joystickButton;
        Image settingsButton;

        Program Program;

        USBH_Mouse mouse;
        USBH_Mouse keyboard;
        USBH_Mouse joystick;

        static public MainWindow(Program program)
        {
            Instance = new MainWindow(program);
        }

        public MainWindow(Program program)
        {
            Program = program;

            // Create a new stack panel, and add it to the window
            stackContent = new StackPanel(Orientation.Horizontal);
            stackTitle = new StackPanel(Orientation.Horizontal);
            stackWindow = new StackPanel(Orientation.Vertical);

            this.Child = stackWindow;

            // Titlebar
            TitleBar titleBar = new TitleBar("Foekie's Desktop");
            titleBar.HorizontalAlignment = HorizontalAlignment.Left;
            stackTitle.Children.Add(titleBar);

            // Apply the necessary properties
            this.Height = SystemMetrics.ScreenHeight;
            this.Width = SystemMetrics.ScreenWidth;
            this.Background = new ImageBrush(Resources.GetBitmap(Resources.BitmapResources.background)) { Stretch = Stretch.None };


            // add settings button
            Bitmap settingsImage;
            settingsImage = Resources.GetBitmap(Resources.BitmapResources.icon_Settings);
            settingsImage.MakeTransparent(Color.Black);

            settingsButton = new Image(settingsImage);
            settingsButton.HorizontalAlignment = HorizontalAlignment.Left;
            settingsButton.SetMargin(10, 10, 0, 0);
            settingsButton.TouchDown += openSettings;

            stackContent.Children.Add(settingsButton);

            // add joystick button
            Bitmap joystickImageOff;
            joystickImageOff = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
            joystickImageOff.MakeTransparent(Color.Black);

            joystickButton = new Image(joystickImageOff);
            joystickButton.HorizontalAlignment = HorizontalAlignment.Left;
            joystickButton.SetMargin(10, 10, 0, 0);

            stackContent.Children.Add(joystickButton);


            // add title and content to the window stack.
            stackWindow.Children.Add(stackTitle);
            stackWindow.Children.Add(stackContent);
        }

        public void UpdateWindow()
        {
            // Would it be possible with a method?
            bool joystickConnected = true;

            if (joystickConnected)
                joystickButton.Bitmap = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);
        }

        public void openSettings(object sender, TouchEventArgs args)
        {
            // removed line so i could compile
            //new Settings(Program);
        }

Example of using a singleton.


public static void Main()
        {
            MainWindow wnd = new MainWindow(program);

            Thread.Sleep(5000);

            // after 5 seconds change the joystick icon.
            MainWindow.Instance.UpdateWindow();

            // ...
        }


#12

Ok, so i fixed it for you :slight_smile:

I refactored some of your names to match Microsoft’s coding best practices :wink:

Basically, you were storing the image that you use on the control as a field in your class, rather than the control. You want to re-use the control just changing the image, so i did that.

It also looked like you were wanting some sort of singleton pattern class so you just have one instance of MainWindow which you can reference from anywhere. Now you can just use MainWindow.Instance.whatever().


public class MainWindow : Window
    {
        public static MainWindow Instance { get; private set; }

        StackPanel stackTitle;
        StackPanel stackContent;
        StackPanel stackWindow;

        Image joystickButton;
        Image settingsButton;

        static Program program;
        public static Program Program
        {
            get { return MainWindow.program; }
            set 
            { 
                MainWindow.program = value;
                Instance = new MainWindow();
            }
        }

        USBH_Mouse mouse;
        USBH_Mouse keyboard;
        USBH_Mouse joystick;

        static public MainWindow()
        {
        }

        private MainWindow()
        {
            // Create a new stack panel, and add it to the window
            stackContent = new StackPanel(Orientation.Horizontal);
            stackTitle = new StackPanel(Orientation.Horizontal);
            stackWindow = new StackPanel(Orientation.Vertical);

            this.Child = stackWindow;

            // Titlebar
            TitleBar titleBar = new TitleBar("Foekie's Desktop");
            titleBar.HorizontalAlignment = HorizontalAlignment.Left;
            stackTitle.Children.Add(titleBar);

            // Apply the necessary properties
            this.Height = SystemMetrics.ScreenHeight;
            this.Width = SystemMetrics.ScreenWidth;
            this.Background = new ImageBrush(Resources.GetBitmap(Resources.BitmapResources.background)) { Stretch = Stretch.None };


            // add settings button
            Bitmap settingsImage;
            settingsImage = Resources.GetBitmap(Resources.BitmapResources.icon_Settings);
            settingsImage.MakeTransparent(Color.Black);

            settingsButton = new Image(settingsImage);
            settingsButton.HorizontalAlignment = HorizontalAlignment.Left;
            settingsButton.SetMargin(10, 10, 0, 0);
            settingsButton.TouchDown += openSettings;

            stackContent.Children.Add(settingsButton);

            // add joystick button
            Bitmap joystickImageOff;
            joystickImageOff = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
            joystickImageOff.MakeTransparent(Color.Black);

            joystickButton = new Image(joystickImageOff);
            joystickButton.HorizontalAlignment = HorizontalAlignment.Left;
            joystickButton.SetMargin(10, 10, 0, 0);

            stackContent.Children.Add(joystickButton);


            // add title and content to the window stack.
            stackWindow.Children.Add(stackTitle);
            stackWindow.Children.Add(stackContent);
        }

        public void UpdateWindow()
        {
            // Would it be possible with a method?
            bool joystickConnected = true;

            if (joystickConnected)
                joystickButton.Bitmap = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);
        }

        public void openSettings(object sender, TouchEventArgs args)
        {
            // removed line so i could compile
            //new Settings(Program);
        }
    }

Example of using a singleton.


public static void Main()
        {
            // setting program initialises the class.
            MainWindow.Program = program;


            Thread.Sleep(5000);

            // after 5 seconds change the joystick icon.
            MainWindow.Instance.UpdateWindow();

            // ...
        }


#13

I cannot get it to work, this is my code:


public class MainWindow : Window
    {
        public static MainWindow Instance { get; private set; }

        public static Program Program
        {
            get { return MainWindow.program; }
            set 
            { 
                MainWindow.program = value;
                Instance = new MainWindow();
            }
        }

        private static StackPanel stack_Title;
        private static StackPanel stack_Content;
        private static StackPanel stack_Window;

        private static Bitmap settingsButton;
        private static Bitmap joystickButton;

        private static USBH_Mouse mouse;
        private static USBH_Mouse keyboard;
        private static USBH_Mouse joystick;
 
        public MainWindow()
        {
            USBHostController.DeviceConnectedEvent += DeviceConnectedEvent;
            USBHostController.DeviceDisconnectedEvent += DeviceDisconnectedEvent;

            // Create a new stack panel, set margins, and bind it to the window
            stack_Content = new StackPanel(Orientation.Horizontal);
            stack_Title = new StackPanel(Orientation.Horizontal);
            stack_Window = new StackPanel(Orientation.Vertical);
            this.Child = stack_Window;

            // Titlebar
            TitleBar titleBar = new TitleBar("Foekie's Desktop");
            titleBar.HorizontalAlignment = HorizontalAlignment.Left;
            stack_Title.Children.Add(titleBar);

            // Create a new window and apply the necessary properties
            this.Height = SystemMetrics.ScreenHeight;
            this.Width = SystemMetrics.ScreenWidth;
            this.Background = new ImageBrush(Resources.GetBitmap(Resources.BitmapResources.background)) { Stretch = Stretch.None };

            settingsButton = Resources.GetBitmap(Resources.BitmapResources.icon_Settings);
            settingsButton.MakeTransparent(Color.Black);
            Image image = new Image(settingsButton);
            image.HorizontalAlignment = HorizontalAlignment.Left;
            image.SetMargin(10, 10, 0, 0);
            image.TouchDown += openSettings;
            stack_Content.Children.Add(image);

            joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
            joystickButton.MakeTransparent(Color.Black);
            Image image2 = new Image(joystickButton);
            image2.HorizontalAlignment = HorizontalAlignment.Left;
            image2.SetMargin(10, 10, 0, 0);
            //image2.TouchDown += openSettings;
            stack_Content.Children.Add(image2);

            stack_Window.Children.Add(stack_Title);
            stack_Window.Children.Add(stack_Content);
        }

        public void UpdateWindow()
        {
            if (GlobalVariables.joystickConnected)
                joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);

            else
            {
                joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
            }

            MainWindow.Program = program;
            MainWindow.Instance.UpdateWindow();
        }

        public void openSettings(object sender, TouchEventArgs args)
        {
            new Settings(Program);
        }

        static void DeviceConnectedEvent(USBH_Device device)
        {
            if (device.TYPE == USBH_DeviceType.Joystick)
            {
                Debug.Print("Joystick Connected");
                joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);
                MainWindow.Instance.UpdateLayout();
            }
        }

        static void DeviceDisconnectedEvent(USBH_Device device)
        {
            if (device.TYPE == USBH_DeviceType.Joystick)
            {
                Debug.Print("Joystick Disconnected");
                joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_JoystickOff);
                GlobalVariables.joystickConnected = false;
            }
        }
    }


Error:

[quote]A first chance exception of type ‘System.NullReferenceException’ occurred in FEZ Cobra Window Application.exe
An unhandled exception of type ‘System.NullReferenceException’ occurred in FEZ Cobra Window Application.exe[/quote]

On line:

           
            if (device.TYPE == USBH_DeviceType.Joystick)
            {
                Debug.Print("Joystick Connected");
                joystickButton = Resources.GetBitmap(Resources.BitmapResources.icon_Joystick);

                //causes error:
                MainWindow.Instance.UpdateLayout();
            }

Have I done something wrong or have I misunderstood something? :frowning:


#14
public static MainWindow Instance { get; private set; }
 
        public static Program Program
        {
            get { return MainWindow.program; }
            set 
            { 
                MainWindow.program = value;
                Instance = new MainWindow();
            }
        }

I don’t see a MainWindow.program field anywhere, also the error is because Instance is null and you cannot set a property of something thats null :stuck_out_tongue:


#15

Firstly, copy my code for the button fields and mainwindow ctor - they have the fix you need.

no need to set the program variable in the update window - if you’re in that method you have an instance of the class already. UpdateWindow should be static. Can you email me your solution and i’ll fix it up/annotate my changes so you can see what i’ve done easier?

markh@ rris.com.au


#16

Done, thanks. Please make sure you delete your email address from the forum. (spam bots)


#17

lol, my email address is all over the net. I don’t get any spam because i host with google apps :slight_smile: I’ve been doing so for years, one of my email addresses was getting 400+ spam a day and i never saw one bit of spam in my inbox (only 60+ regular emails).

I’ll take a look at your solution tomorrow as it’s a bit late now. I don’t have a cobra so i cannot test it however i’ll run it through the in-brain-debugger :wink:


#18

Thank you, let me know when you are done. I have also sent you the modified version by Toshko.

thanks :wink: