Search code examples
uwpwin-universal-app

UWP update Button content in UIThread


I have a button that does a backgroud task (it searches lyrics from the Internet for all music files). And it updates the button content by incrementing the counter as it fetches the lyrics.

    private async void AddLyrics_Click(object sender, RoutedEventArgs e)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            string format = Helper.LocalizeMessage("PostParenthesis");
            HyperlinkButton button = (HyperlinkButton)sender;
            int count = MusicLibraryPage.AllSongs.Count;
            for (searchLyricsCounter = 1; searchLyricsCounter < count + 1; searchLyricsCounter++)
            {
                Music music = MusicLibraryPage.AllSongs[searchLyricsCounter - 1];
                string lyrics = await music.GetLyricsAsync();
                //if (string.IsNullOrEmpty(lyrics))
                //{
                //    lyrics = await Controls.MusicLyricsControl.SearchLyrics(music);
                //    await music.SaveLyricsAsync(lyrics);
                //}
                System.Diagnostics.Debug.WriteLine(searchLyricsCounter);
                button.Content = string.Format(format, addLyricsContent, searchLyricsCounter + "/" + count);
            }
            searchLyricsCounter = 0;
            button.Content = Helper.Localize("AddLyrics");
            Helper.ShowNotification("SearchLyricsDone");
        });
    }

The button is located in a page (SettingsPage) of a Frame in the MainPage. After I switch to another page and change back to SettingsPage, the button stops updating the content, although the thread is still running.

How can I keep the button content updating?


Solution

  • Keep the page on cache. Set NavigationCacheMode property to Enabled or Required.

    On XAML.

    <Page NavigationCacheMode="Enabled">
    
    </Page>
    

    Or in Code-Behind

    public sealed partial class SettingsPage : Page
    {
        public SettingsPage()
        {
            InitializeComponent();
            NavigationCacheMode = NavigationCacheMode.Enabled;
        }
    }
    

    Click event already runs on UI Thread

    private async void AddLyrics_Click(object sender, RoutedEventArgs e)
    {    
        HyperlinkButton button = (HyperlinkButton)sender;
        button.IsEnabled = false; // avoid duplicate clicks
        try
        {
            string format = Helper.LocalizeMessage("PostParenthesis");
            int count = MusicLibraryPage.AllSongs.Count;
            int searchLyricsCounter = 1;
            foreach(Music music in MusicLibraryPage.AllSongs)
            {
                string lyrics = await music.GetLyricsAsync();        
                System.Diagnostics.Debug.WriteLine(searchLyricsCounter);
                button.Content = string.Format(format, addLyricsContent, searchLyricsCounter + "/" + count);
            }        
            button.Content = Helper.Localize("AddLyrics");
            Helper.ShowNotification("SearchLyricsDone");
        }
        finally
        {
            button.IsEnabled = true; // Can click now
        }
    }
    

    Read more about NavigationCacheMode