How to show ProgressBar control while a page is loading? - c#

I have WP7 application with several pages. When a user navigates through them it takes some time to load information. So before showing him/her the page I'd like to show “Loading…” message.
I created progress bar and placed it on the page:
<StackPanel x:Name="progressBarMain" Grid.Row="1" Grid.ColumnSpan="2" Visibility="Collapsed">
<TextBlock Text="Loading..." HorizontalAlignment="Center" VerticalAlignment="Center" />
<ProgressBar Margin="10" Height="30" IsIndeterminate="True"/>
</StackPanel>
And I'm trying to show it (and hide everything else) in the page's constructor, and hide it (and show everything else) in Page.Loaded handler.
public SomePage()
{
InitializeComponent();
Loaded +=OnSomePageLoaded;
progressBarMain.Visibility = Visibility.Visible;
ContentPanel.Visibility = Visibility.Collapsed;
}
private void OnSomePageLoaded(object sender, RoutedEventArgs e)
{
progressBarMain.Visibility = Visibility.Collapsed;
ContentPanel.Visibility = Visibility.Visible;
}
But it doesn’t' work.
Any ideas? Thank you!

Alex demonstrates showing a progress bar while the app is starting up here.
Creating a Splash Screen with a progress bar for WP7 applications. - Alex Yakhnin's Blog

Although you cannot directly manipulate the splash screen (which is static), you can display a popup (by the way, that is exactly what is done in Alex's solution) and wait for a background (read: loading) operation to complete.

Yes, you'll need to create a separate XAML Pop-up page that is loaded when the app boots up. For more details on Splash Screens, there is a code sample from MSDN:
"Code Sample for Splash Screen"

Related

Icon not showing when asked to

My app is blocking when i want to navigate to certain view, so i want to show a load icon. The problem is the icon never shows when expected. The view changes and i never see the icon, but if i go back the icon is there.
I tried using an async task to do the navigation, but the navigation doesn't work in a task, i guess.
Any suggestions or ideas?
XAML Code:
<UserControl xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:fa="http://schemas.fontawesome.io/icons/">
<Grid>
<Listbox ItemsSource={Binding ItemsList}>
</Listbox>
<Canvas Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="-550, 180, 0, 0">
<fa:ImageAwesome Visibility="{Binding LoadingIcon, UpdateSourceTrigger=PropertyChanged}"
Icon="Spinner"
Spin="True"
Canvas.Left="56"
Canvas.Top="-17" />
</Canvas>
</Grid>
<UserControl.InputBindings>
<KeyBinding Key="Enter" Command="{Binding NavigateToMainMenuCommand}"/>
</UserControl.InputBindings>
</UserControl>
ViewModel:
public class LoginViewModel: ViewModelBase, INotifyPropertyChanged, INavigationAware
{
public InicioContableViewModel(IRegionManager regionManager,
IEventAggregator eventAggregator)
{
_regionManager = regionManager;
_eventAggregator = eventAggregator;
NavigateToMainMenuCommand = new DelegateCommand(NavigateToMainMenu);
LoadingIcon = Visibility.Hidden;
}
public DelegateCommand NavigateToMainMenuCommand { get; private set; }
private Visibility loadingIcon;
public Visibility LoadingIcon
{
get
{
return loadingIcon;
}
set
{
SetProperty(ref loadingIcon, value, nameof(LoadingIcon));
NotifyPropertyChanged(nameof(LoadingIcon));
}
}
private void NavigateToMainMenu()
{
LoadingIcon = Visibility.Visible;
string mainUri = nameof(SomeRoute.MainMenu);
_regionManager.RequestNavigate(Regions.MainRegion, mainUri);
}
}
In your Icon's properties, try to set Build Action to Resource.
WPF uses the UI thread to do things like handle mouse movement, change icons when you tell it to and to switch out one view for another. All one thread.
When that thread is busy doing something then nothing is likely to change in your UI until it's finished.
Hence, if you tell it to make something visible AND navigate, you can well find all that happens visually is the navigation. Because it has no time to show your icon.
Try making your method async and giving it a little time:
private async void NavigateToMainMenu()
{
LoadingIcon = Visibility.Visible;
await Task.Delay(60);
string mainUri = nameof(SomeRoute.MainMenu);
_regionManager.RequestNavigate(Regions.MainRegion, mainUri);
}
That task.delay should give it enough time to redraw a bit of ui.
If you need a loading icon and the thing you are navigating to is blocking then I suspect you have other problems. It's likely that whatever this new view is doing to initialise should be asynchronous. Maybe with data access etc on background threads.
You may most likely make use of the functions:- InvalidateVisual() or UpdateLayout(). Those will force to redraw and may resolve your icon visibility issues.
My app is blocking when i want to navigate to certain view, so i want to show a load icon.
If the app is blocking, you cannot show the icon, because, you know, the app is blocked. You have to remove the blocking, that is, make navigation itself quick, and do whatever initialization asynchronously. The view you're navigating to may need stuff from a database or connection to a usb device, but it won't need it immediately. You can still query the database or whatever in the background after the view is shown.
show wait indicator-> navigate -> creates view model -> starts initializion task -> initialization completes -> hide wait indicator

Stop screen capture on UWP app in TaskView of Windows 10

I stop screen capturing on my UWP app by
ApplicationView.GetForCurrentView().IsScreenCaptureEnabled = false;
However, the app still shows its preview on Taskview of Windows 10
Can someone let me know how to disable the app's preview on Task view
This is the current TaskView
and this is how I need it
Capturing an app's thumbnail looks like a system behavior, and I don't know how to disable it.
But since the capture only happens when the user presses Alt+Tab or clicks the task switch button on the task bar, there is a chance to cover the app with an overlay before system takes a screen capture of the app.
First add an opaque overlay, and set its initial visibility as Collapsed.
<Grid>
<TextBlock FontSize="50" Text="Your controls here!" />
<Grid Background="Black" x:Name="overlay" Visibility="Collapsed" />
</Grid>
Then register a handler for app window's Activated event,
Window.Current.Activated += Current_Activated;
Display/Hide the overlay when window is deactivated/activated,
private void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
{
overlay.Visibility = Visibility.Visible;
}
else
{
overlay.Visibility = Visibility.Collapsed;
}
}

Windows Store 8.1. XAML Progress Bar between pages

I am having a problem with a page in my Windows 8.1 Store App that is taking a long time to render - it is a grid with a number of columns and rows that gets bound to data on loading of the page.
It is not the loading of the data that is slow but the actual binding of the data to the grid.
I ideally want to display a dialog bar to indicate to the user that something is loading and they have clicked on the previous navigate button okay.
I saw someone mention the possibility of having a "loading page" which only has a progress bar in it - and I thought this solution might work but I can't work out in what event of the loading page should I navigate to the actual page.
i.e.
User clicks button which calls
this.Frame.Navigate(typeof(LoadingPage));
Loading Page displays a progress bar
I know need to be able to call
this.Frame.Navigate(typeof(ActualPage));
The user sees the progress bar whilst ActualPage loads.
Any suggestions would be greatly appreciated thanks!
Thanks to the support team at DEVExpress I have a solution to my problem.
Firstly on the page that takes time to load I have wrapped my Grid in a ContentControl
<ContentControl Visibility="Collapsed" Name="Content">
<!-- Grid in here -->
</ContentControl>
I then added a TextBlock which I will use as to display "Loading..." to my page. I have called this control indicator.
<TextBlock x:Name="indicator" Text="Loading..." />
I have attached the following method to the Loaded event of the page which uses a timer
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
indicator.Visibility = Windows.UI.Xaml.Visibility.Visible;
DispatcherTimer t = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
t.Tick += (dd, ee) =>
{
t.Stop();
Content.Visibility = Windows.UI.Xaml.Visibility.Visible;
};
t.Start();
}
Then when the gridcontrol has Loaded I hide the indicator TextBlock
void gridControl_Loaded(object sender, RoutedEventArgs e)
{
indicator.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
This works perfectly for me. I can't use the Windows 8 ProgressBar control because the animation is loaded on the same thread that loads the grid - but I am happy enough to have any indicator.
Also thanks Brian Stump for pointing me in the right direction.
First, I will suggest using a ListView or GridView to display your databound objects because of build-in UI virtualization.
However, maybe this will work for your situation.
Do you know when your page is ready to display? If so, place a progress ring in front of your grid while it loads in the background.
<Grid x:Name="FullPageGrid">
<Grid x:Name="YourGridContent">
</Grid>
<Grid Background="White" Visibility="Visible" x:Name="ProgressRingGrid">
<ProgressRing IsActive="True"></ProgressRing>
</Grid>
</Grid>
When the data is fully loaded, change the visibility of the "ProgressRingGrid" to Visibility="Collapsed"

How to programmatically hide the keyboard

I have a textbox with a button inside (Telerik's RadTextBox with an Action configured).
When the user presses the Action, a progress bas is displayed, the screen goes dark, and some magic happens.
My problem is that since the action doesn't result in the textbox losing focus, the on-screen keyboard is not hidden, and keeps covering half the screen.
I would like to programmatically hide the on-screen keyboard, but don't know how.
Just set focus to the main page:
this.Focus();
this will focus a control that doesn't use the keyboard and thus hide the keyboard. Unfortunately there is no API to the keyboard to hide it.
Instead try disabling and then enabling the textbox in question in an appropriate place (like once a query has been submitted or an action triggered):
TextBox.IsEnabled = false;
TextBox.IsEnabled = true;
(Via https://stackoverflow.com/a/23905874/1963978)
Not clean, but it does the job (in Windows 10 mobile).
here lot solution is available for a Textblock only but in my case AutoCompleteBox
<toolkit:AutoCompleteBox Name="autoComplateTxt"
Grid.Row="4"
Margin="15,5,2,10"
Padding="0"
Height="65"
Text=""
BorderThickness="1"
BorderBrush="Black"
VerticalAlignment="Center"
DropDownClosed="autoComplateTxt_DropDownClosed"
/>
private void autoComplateTxt_DropDownClosed(object sender, RoutedPropertyChangedEventArgs<bool> e)
{
this.Focus();
}

Airspace Issue: Popup content over WindowsFormsHost will not be updated

i'm stuck with airspace problem. My WPF app hosts a winform component. I want to display a popup with some "waiting-please" text during component loading and long activities. Here I get my problem: popup is correctly display but when I handle component's busy event I cannot update popup content. Here some code XAML:
<WindowsFormsHost Name="wfh" Grid.Row="1" Grid.Column="0" ></WindowsFormsHost>
<Popup x:Name="Overlay" AllowsTransparency="True" Placement="Center"
StaysOpen="True"
IsOpen="True"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}}">
<TextBlock Name="tbWait" Foreground="Red" />
</Popup>
and c#:
myWinformComponent.Event => (s, e) =>
{
tbWait.Text = e.IsBusy ? "Loading..." : string.Empty;
}
I know what is the Airspace problem with WinForm and WPF but I was supposed that keep the popup always open let me display any content ove the windowformshost.
EDIT: I'm placing some breakpoints into the code behind and I see the Text property change correctly. This changes are not display into the UI.
Have you any workaround or solution?
Thank you guys!
According with #HansPassant comment, I can force redraw with these lines:
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) {
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
Maybe it's not the most elegant solution, but it's a working patch to my issue.
Unfortunately, you can't display any WPF content over a WindowsFormsHost. I spent a long time fighting this quirk myself, until I finally gave up and rearraged the UI to make the overlay not have to be over the WinForms component.

Categories