Force a view to refresh? - xaml

I'm trying to do a loading icon where once you tap on the icon, it will call the following handler:
private void refresh_btn_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
refresh_btn.Visibility = System.Windows.Visibility.Collapsed;
loading_icon.Visibility = System.Windows.Visibility.Visible;
refreshMix();
}
private void refreshMix()
{
...
refresh_btn.Visibility = System.Windows.Visibility.Collapsed;
loading_icon.Visibility = System.Windows.Visibility.Visible;
}
However, the view doesn't seem to auto-reload after I change the icon visibilities before calling refreshMix(). Is there a way to force the page to reload itself?

You are probably doing some lengthy work in refreshMix() in UI thread, right? Do this work in background thread and UI thread will be free to update page.

You need set Collapsed before Visible :
control.Visibility = System.Windows.Visibility.Collapsed;
control.Visibility = System.Windows.Visibility.Visible;

Within Silverlight there is no concept of page or view re-loading. When you change the properties of any visual element, this will be reflected on the screen the next time it is rendered.

Related

How to close ComboBox list items when moving application window of my WinRT/C++ UWP application?

I have a pair of ComboBox controls having IsEditable() true as well as false.
When I am scrolling through my application or moving my application window (by clicking on the title bar) with list popup open, I would like to close the ComboBox list popup as otherwise there would be a weird delay in aligning the list correctly below the control.
Is this possible in UWP with WinRT/C++? If so, kindly suggest how to.
I did an investigation to find if any events are there to handle in such a scenario when ComboBox control is essentially displaced from initial position while moving the app window/scrolling the app, but couldn't find any help.
Edit: Adding ComboBox image from XAML Controls Gallery to demonstrate the behaviour. In case if IsEditable set as true, when popup is opened and application is scrolled then popup goes outside the window. Instead I would like to dismiss the popup itself. However, if IsEditable is set as false then we cannot scroll until the popup is dismissed.
Update: The code I tested for PointerWheelChanged
void CBFile2022X::OnPointerWheelChangedHandler( Windows::Foundation::IInspectable const& sender,
Windows::UI::Xaml::Input::PointerRoutedEventArgs const& eventargs )
{
OutputDebugString( L"PointerWheelChanged" );
if( ComboBox != nullptr )
{
ComboBox.IsEnabled( false );
ComboBox.IsEnabled( true );
}
}
I have to say that currently there is no event to detect if the application window is moved or changed its location.
Update:
You could handle the UIElement.PointerWheelChanged Event which will be fired when users scroll the mouse wheel. You could set the IsEnabled property of the ComboBox to false first and then set it to true, this will make the ComboBox lose its focus. Like:
private void Mypanel_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
FontsCombo.IsEnabled = false;
FontsCombo.IsEnabled = true;
}
Update2:
If you are using a ScrollViewer you could try to handle the ScrollViewer.ViewChanging Event.
private void ScrollViewer_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
FontsCombo.IsEnabled = false;
FontsCombo.IsEnabled = true;
}

UWP Light dismiss ContentDialog

Is there a way to make the ContentDialog light dismiss?, so when the user clicks on any thing outside the ContentDialog it should be closed.
Thanks.
By default, ContentDialog is placed in PopupRoot. Behind it, there is a Rectangle which dim and prevent interaction with other elements in the app. You can find it with help of VisualTreeHelper and register a Tapped event to it, so when it's tapped you can hide ContentDialog.
You can do this after calling ShowAsync outside ContentDialog code or you can do it inside ContentDialog code. Personally, I implement a class which derives from ContentElement and I override OnApplyTemplate like this:
protected override void OnApplyTemplate()
{
// this is here by default
base.OnApplyTemplate();
// get all open popups
// normally there are 2 popups, one for your ContentDialog and one for Rectangle
var popups = VisualTreeHelper.GetOpenPopups(Window.Current);
foreach (var popup in popups)
{
if (popup.Child is Rectangle)
{
// I store a refrence to Rectangle to be able to unregester event handler later
_lockRectangle = popup.Child as Rectangle;
_lockRectangle.Tapped += OnLockRectangleTapped;
}
}
}
and in OnLockRectangleTapped:
private void OnLockRectangleTapped(object sender, TappedRoutedEventArgs e)
{
this.Hide();
_lockRectangle.Tapped -= OnLockRectangleTapped;
}
Unfortunately ContentDialog does not offer such behavior.
There are two alternatives you can consider:
Popup - a special control built for this purpose, which displays dialog-like UI on top of the app content. This control actually offers a IsLightDismissEnabled for the behavior you need. Since the Anniversary Update (SDK version 1607) also has a LightDismissOverlayMode, which can be set to "On" to automatically darken the UI around the Popup when displayed. More details are on MSDN.
Custom UI - you can create a new layer on top of your existing UI in XAML, have this layer cover the entire screen and watch for the Tapped event to dismiss it when displayed. This is more cumbersome, but you have a little more control over how it is displayed

How to animate SettingsFlyout on dismiss

In Windows 8.1, I'm using the new SettingsFlyout control. The flyout animates in correctly and will animate out if you use the control's built-in back button to return to the Settings Charm flyout. But if you light dismiss by clicking outside the flyout, it disappears without a transition animation.
How do you animate a transition out when you light dismiss the SettingsFlyout? (I don't want to return to the Settings Charm flyout, I just want it to slide out on a light dismiss.)
Matt, what you want to do should be easily achievable but is currently not supported by the XAML SettingsFlyout API out of the box. As Jerry points out, there are transitions that allow an animate out effect (in XAML you want EdgeUIThemeTransition). Unfortunately, there is no API support on SettingsFlyout to add this transition, but you can get it to work using your own private popup to host the SettingsFlyout (more on this below):
public sealed partial class SettingsFlyout1 : SettingsFlyout
{
Popup _p;
Border _b;
public SettingsFlyout1()
{
this.InitializeComponent();
BackClick += SettingsFlyout1_BackClick;
Unloaded += SettingsFlyout1_Unloaded;
Tapped += SettingsFlyout1_Tapped;
}
void SettingsFlyout1_BackClick(object sender, BackClickEventArgs e)
{
_b.Child = null;
SettingsPane.Show();
}
void SettingsFlyout1_Unloaded(object sender, RoutedEventArgs e)
{
if (_p != null)
{
_p.IsOpen = false;
}
}
void SettingsFlyout1_Tapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true;
}
public void ShowCustom()
{
_p = new Popup();
_b = new Border();
_b.ChildTransitions = new TransitionCollection();
// TODO: if you support right-to-left builds, make sure to test all combinations of RTL operating
// system build (charms on left) and RTL flow direction for XAML app. EdgeTransitionLocation.Left
// may need to be used for RTL (and HorizontalAlignment.Left on the SettingsFlyout below).
_b.ChildTransitions.Add(new EdgeUIThemeTransition() { Edge = EdgeTransitionLocation.Right });
_b.Background = new SolidColorBrush(Colors.Transparent);
_b.Width = Window.Current.Bounds.Width;
_b.Height = Window.Current.Bounds.Height;
_b.Tapped += b_Tapped;
this.HorizontalAlignment = HorizontalAlignment.Right;
_b.Child = this;
_p.Child = _b;
_p.IsOpen = true;
}
void b_Tapped(object sender, TappedRoutedEventArgs e)
{
Border b = (Border)sender;
b.Child = null;
}
}
Full solution for this sample: https://github.com/finnigantime/Samples/tree/master/examples/Win8Xaml/SettingsFlyout_AnimateOut
I think SettingsFlyout should have API support for your scenario, so I filed a work item on the XAML team. In the future, such requests/issues can be raised on the MSDN forum as well (moderated by MSFT folks). The limitation here is that SettingsFlyout is implemented on top of Popup with IsLightDismissEnabled="True", and the light-dismiss event currently closes the Popup immediately without allowing unloading child transitions to run. I think this can be overcome and transitions can be supported at the SettingsFlyout API level to enable your scenario.
You need to use the HideEdgeUI animation
Read this: http://msdn.microsoft.com/en-us/library/windows/apps/jj655412.aspx

Win 8.1 Metro Hub Navigation

In a Hub view App with subItems Pages, my question is when I navigate to a sub item detail Page and then use command navigate goback, the view always returns to pageroot hub section01.
How can I return the MainHub Page to the original calling section that went to the sub page in the first place?
My research has been fruitless. I don't think snaps are my answer but hey any advice is appreciated.
I apologize if this is a very simple question but...
Thx.
Ok. Thanks for the answers. After looking at this problem for three days I have found a solution but not quite an answer.
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
By enabling Navigation Caching the page will return to it's sender position. However I still desire to return to the Hub root page to a specific section. If anyone still has info on how to achieve this I would be grateful.
Seasons Greetings.
Well the newbie here has also discovered the MyHub.ScrollToSection(MyHub.Sections[0]);
This allows you to navigate directly to a section thereby bringing it into the current view.
I'm trying to find an answer to the same question. This is what I've found so far. I welcome any better solutions.
Option 1
Enable caching for the page. Note that this must be set in the page constructor or XAML. This will increase memory usage but will improve performance of your app when you navigate back to a cached page.
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
More information here: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.page.navigationcachemode.aspx
Option 2
Manually save a controls state between page navigations. The example below is using the NavigationHelper class which is added to a new Windows Store project by default.
private void OnNavigationHelperSaveState(obj sender, SaveStateEventArgs e)
{
e.PageState["SelectedSection"] = this.MainHub.SectionsInView;
}
private void OnNavigationHelperLoadState(obj sender, LoadStateEventArgs e)
{
if (e.PageState != null)
{
var sections = e.PageState["SelectedSection"] as IList<HubSection>;
if (sections != null && sections.Any())
{
this.MainHub.ScrollToSection(sections[0]);
}
}
}
More information here: http://msdn.microsoft.com/en-gb/library/windows/apps/hh986968.aspx
you could get the Hub's descendant scrollviewer and register to scrollchanged events, store the scrollOffsets and restore them as soon as the user navigates back to the page by applying the values to the hub's scrollviewer.
I guess you would have to register to the hub's loaded event to get the descending scrollviewer (you can use an Extension method from WinRt XAML Toolkit that allows you to get the descendants by Type (e.g. Scrollviewer)
greetings!
you can delete un back stack with this :
if(this.Frame.CanGoBack)
{
this.Frame.BackStack.RemoveAt(0);
}
Have you tried what i suggested?
Unforunately Hub can't be extended to do this and access it's Scrollviewer so you have to do this with an attached Property or plainly in your page.cs .
First you register an handler for the Loaded event of your hub. In the handler you get the descending scrollviewer (with the help of WINRT XAML Toolkit maybe) and register for it's ViewChanged Event.
You store the paremeters you like somewhere they don't get deleted on page navigation and restore and attach them to the scrollviewer on backwards-navigation.
I can give you example code in the afternoon.
Greetings
It's not a ridiculous request. Try this:
public static class Concurrency
{
public static HubSection GotoSection { get; set; }
}
public class MainPage : Page
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (Concurrency.GotoSection != null)
MainHub.ScrollToSection(Concurrency.GotoSection);
Concurrency.GotoSection = null;
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Concurrency.GotoSection = MainHub.SectionsInView.First();
base.OnNavigatedFrom(e);
}
}
The reason this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; may not be the correct solution is because you might want your hub to be refreshed. If the detail page resulted in an edit (or especially a delete) a back navigation would show stale data, and subject your app to un unexpected state if the user interacts with dead data.
Best of luck!
Enable cache mode on your page at initialization
public MainHubPage()
{
. .......
this.NavigationCacheMode = NavigationCacheMode.Enabled;
.......
}
You need to add Loaded method to Page constructor.
MainHub.Loaded += async (s, e) => await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//here you can scroll
MainHub.ScrollToSection(Loyaltysection);
});

Windows Phone 7 Control Caching - 'Element is already the child of another element'

I'm trying to speed up my windows phone 7 page load times. I have a 'static' page that has a dynamically created in a Panorama control - static meaning that the content never changes.
On the first load I look at my config file, create the individual PanoramaItem controls and add them to the main Panorama control. I'm trying to keep a List in a static place so that the initial creation would only happen once and I could just add a fully rendered version to my Panorama control when the page was rendered.
Works fine on first load, but when I try to add the cached PanoramaItems to the Panorama control I get the message "Element is already the child of another element". This makes sense since I already added before. But I can see a way to disconnect the PanoramaItems with the first Panorama control...
I could be going about the control caching thing all wrong as well... Let me know if there's another way to do this.
You can use Panorama.Items.Remove(pivotItem) for this
As an example
With the following page fields
PanoramaItem pi;
bool blahShown = false;
On the press of this button, the control is first instantiated and displayed and on subsequent presses removed and readded without instantiation.
private void button1_Click(object sender, RoutedEventArgs e)
{
if (pi == null) {
pi = new PanoramaItem();
pi.Header = "blah";
}
if (blahShown) {
Pano.Items.Remove(pi);
blahShown = false;
} else {
Pano.Items.Add(pi);
blahShown = true;
}
}