Search code examples
c#xamluwpuwp-xamlapp-startup

Change button property during an app startup


I have made a simple UWP app that comunicates with a network device. I have implemented an async method await GetStatus("PW?") which sends particular command and returns the device's status. On the other hand, I need to implement SetPowerButtonProperties() method while the app is loading so I could set, in this case, content and color of the specific button after the UI is rendered. I have added Debug.WriteLine("yes"); just to see if the method is indeed called. Where I need to put this method?

public async void SetPowerButtonProperties()
{
    if (await GetStatus("PW?") == "PWON")
    {
        Debug.WriteLine("yes");
        powerButton.Content = "Power OFF";
        powerButton.Background = new SolidColorBrush(Colors.DarkRed);
    }
    else
    {
        Debug.WriteLine("no");
        powerButton.Content = "Power ON";
        powerButton.Background = new SolidColorBrush(Colors.DarkGreen);
    }
}

I have tried to initiate a MainPage class in App.xaml.cs so I could access the SetPowerButtonProperties() method and button's x:Name:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();
        var mainPage = new MainPage();
        mainPage.SetPowerButtonProperties();

        rootFrame.NavigationFailed += OnNavigationFailed;

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }

        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }
    Window.Current.Activate();

    if (e.PrelaunchActivated == false)
    {
        if (rootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
        // Ensure the current window is active
        Window.Current.Activate();
    }
}

In this case, in the output I get "yes" after the UI is rendered which indicates that method is indeed called, but content and color of the button are not changed. Notice, I have also set x:FieldModifier="public" in MainPage.xaml to public because at first I got an error.

<Button Content="Power ON" x:Name="powerButton" Click="PowerButtonClick" FontSize="20" x:FieldModifier="public"/>


Solution

  • In UWP, a Page instance is instantiated by Frame.Navigate method. Thus your approach does not work.

    Alternatively, you can utilize Page.OnNavigatedTo method for doing something to the Page instance. In addition, if you want to hand over some data (string, char, numeric, or GUID) from the App to the Page, you can utilize paramater of Frame.Navigate(TypeName, Object) method.

    App.xaml.cs

    sealed partial class App : Application
    {
        ...
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;
            ...
            if (e.PrelaunchActivated == false)
            {
                if (rootFrame.Content == null)
                {
                    var parameter = "data to be handed over";
                    rootFrame.Navigate(typeof(MainPage), parameter);
                }
                Window.Current.Activate();
            }
        }
        ...
    }
    

    MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    
        private bool isFirst = true;
    
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (isFirst)
            {
                isFirst = false;
                var parameter = e.Parameter; // "data to be handed over"
                // Do something.
            }
            base.OnNavigatedTo(e);
        }
    }