How to programatically scroll a ScrollViewer to the top in uwp xaml? - xaml

I have applied ScrollViewer to a user control which automatically scrolls to the bottom if height exceeds.
Now my page is closing having the scrollbar at the bottom position and it remains at the bottom when I reopen the page.
How can I reset the scrollbar to the top every time I open that page.
<ScrollViewer x:Name="myScrollViewer">
<Grid Margin="0,0,0,40">
</Grid>
</ScrollViewer>

ScrollViewer provides the ChangeView method, which can be used to adjust the scrolling state:
// scroll to top
myScrollViewer.ChangeView(0, 0, 1);
You can call this method after the page is loaded to scroll the ScrollViewer to the top.
Update
If you want to access the control on the page in the ViewModel, there are two ways:
1. Public control
This method means that you need to create a public page instance, and then expose the control in XAML, as shown below:
ScrollViewerPage.xaml
<ScrollViewer x:Name="myScrollViewer" x:FieldModifier="public">
<!-- your code -->
</ScrollViewer>
ScrollViewerPage.xaml.cs
public sealed partial class ScrollViewerPage : Page
{
public static ScrollViewerPage Current;
public ScrollViewerPage()
{
this.InitializeComponent();
Current = this;
}
}
After the page is loaded, you can use this code to access the ScrollViewer.
ScrollViewerPage.Current.myScrollViewer.ChangeView(0, 0, 1);
2. Define control variable/property in ViewModel
You can define a variable or property (public) of type ScrollViewer in the ViewModel, and then assign a value to the property when the page loads, and then you can access the ScrollViewer by accessing the property in the ViewModel.
MyViewModel.cs
public class MyViewModel
{
public ScrollViewer MyScrollViewer { get; set; }
// Other code
}
ScrollViewerPage.xaml.cs
public ScrollViewerPage()
{
this.InitializeComponent();
var vm = new MyViewModel();
vm.MyScrollViewer = myScrollViewer;
}

Related

XAMARIN prevent page loading after tap on ShellContent (DataTemplate)

I made some progress on my android app. Currently I struggle to find solution to this problem
(Code reference in my older question Creating nested navigation in Xamarin shell)
As selector does his job, this DataTemplate will be selected as NavigationHeaderTemplate
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
if (item is ShellGroupItem && list.Contains(((ShellGroupItem)item).Title))
{
// Make sure a header item is not clickable.
((ShellGroupItem)item).IsEnabled = false;
return NavigationHeaderTemplate;
}
else
return NavigationItemTemplate;
}
So far, Selector only once check for each NavigationHeaderTemplate (as it should be), and for NavigationItemTemplate it checks every time visibility changes (as it should maybe be, its not quite optimal but it works properly)
After first tap on NavigationHeaderTemplate it only changes visibility of its items (thats correct) but after another tap it changes visibility and goes to AboutPage.
As you see in selection phase NavigationHeaderTemplate should be set as disabled
((ShellGroupItem)item).IsEnabled = false;
But somehow at second tap it goes to AboutPage.
<ShellContent Title="Header" ContentTemplate="{DataTemplate local:AboutPage}"/>
My question is:
How to prevent Header to load pages, it should only change visibility of items (items are used for links)
This doesn't work
<ShellContent Title="Header" ContentTemplate="{DataTemplate local:AboutPage}" IsEnabled="False"/>
After first tap on NavigationHeaderTemplate it only changes visibility of its items (thats correct) but after another tap it changes visibility and goes to AboutPage.
You can try to change FlyoutItemTemplateSelector by following code:
public class FlyoutItemTemplateSelector : DataTemplateSelector
{
public DataTemplate NavigationHeaderTemplate { get; set; }
public DataTemplate NavigationItemTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
if (item is ShellGroupItem && ((ShellGroupItem)item).Title == "Header")
{
// Make sure a header item is not clickable.
((ShellGroupItem)item).IsEnabled = false;
return NavigationHeaderTemplate;
}
else
return NavigationItemTemplate;
}
}
I tap the header one or more time, it just change visibility of its items.

UWP navigation from child page frame to main page frame

I am developing an UWP app, I am getting an issue with back root frame navigation, I have main page in that I have frame, I navigate all pages into this frame ,, dashboard.xaml, orders.xaml....etc, I my orders.xaml I have another frame...in that frame I navigate 3 forms(xaml pages with a cancel button) when I hit cancel buton in any of those pages, I need to navigate to my orders page back... So I am facing problem with getting main page frame to navigate my Orders.xaml into that,,please help me. Thanks in advance
There are multiple ways to achieve what you want. For example, you can define a public static property in Mainpage that exposes the Frame.
public sealed partial class MainPage : Page
{
public static Frame MainPageFrame;
public MainPage()
{
this.InitializeComponent();
//Frame1 is the name of the Frame in XAML
MainPageFrame = Frame1;
}
...
}
And then in the order details page, use this property to navigate.
MainPage.MainPageFrame?.Navigate(typeof(Orders));
Or you can take advantage of VisualTreeHelper and get the parent Frame i.e "Frame1" like:
//this.Frame gets the Frame holds the order details page (i.e "Frame2")
FindParent<Frame>(this.Frame)?.Navigate(typeof(Orders));
The FindParent method here is a help method uses VisualTreeHelper.GetParent method like the following:
public static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
var parentObject = VisualTreeHelper.GetParent(dependencyObject);
if (parentObject == null) return null;
var parent = parentObject as T;
return parent ?? FindParent<T>(parentObject);
}
This should do it:
Frame.Navigate(typeof(orders));

UWP - Close my content dialog on click on the blank area

I have created a content dialog for my UWP app which involves a centralized UI Element and a surrounding blank area.But content dialog does not have a property like "IsLightDismissEnabled" to close the dialog on click on an area except the UIELEMENT area.How can I achieve it?
In the code behind your content dialog:
public sealed partial class CustomDialog : ContentDialog
{
public CustomDialog()
{
this.InitializeComponent();
Boolean isHide;
Window.Current.CoreWindow.PointerPressed += (s, e) =>
{
if (isHide)
Hide();
};
PointerExited += (s, e) => isHide = true;
PointerEntered += (s, e) => isHide = false;
}
}
There are few options that I can think of:
Use popup (like uruk suggested) and add your controls inside, create the popup at desired location (you could also use binding here if you want to show the popup at location depending on user input at runtime Popup has HorizontalOffset and VerticalOffset properties)
Create a parent view that is taking up the whole page but is transparent, then add your UI elements at the center and attach tap/click events to the transparent view. These events are going to just close remove/collapse the transparent view which contains the other elements inside (Either by binding of values or by setting the values to the UI elements).
Example or popup usage:
<Popup x:Name="MenuPopUp"
IsLightDismissEnabled="True"
HorizontalOffset="{Binding HorizontalOffset}"
VerticalOffset="{Binding VerticalOffset}"
IsOpen="{Binding IsOpen, Mode=TwoWay}">
<Grid>
YOUR ELEMENTS HERE
</Grid>
</Popup>
Content dialog is a modal dialog. Why don't you use a Popup or a child class of it? It's non-modal, and it already has the IsLightDismissEnabled property you just mentioned.
<Popup x:Name="MenuPopUp"
IsLightDismissEnabled="True"
LostFocus="MenuPopUp_LostFocus"/>
In CS
private void MenuPopUp_LostFocus(object sender, RoutedEventArgs e)
{
MenuPopup.IsOpen = false;
}

is it possible to edit MainPage.xaml from C# code?

In my case in need change this
<DrawinSurfaceBackgroundGridgx:Name="DrawingSurfaceBackground"Loaded="DrawingSurfaceBackground_Loaded">
</DrawingSurfaceBackgroundGrid>
to this
<Grid>
<phone:WebBrowser Name="MiniBrowser" Visibility="Collapsed"/>
<!--LayoutRoot is the root grid where all page content is placed-->
<DrawingSurfaceBackgroundGridx:Name="DrawingSurfaceBackground"Loaded=
"DrawingSurfaceBackground_Loaded">
</DrawingSurfaceBackgroundGrid>
</Grid>
When unity3d build default project there is a default MainPage. I need too add a webbrowser component in this mainpage from my unity3d plugin. And then i need to call browser navigate and subscribe to some browser events like loadCompleted Is it possible? Plese give me an example
You can get add/remove items programatically. If you can access the MainPage class you can get to it's content, which is the grid, and to its children which is an UIElementCollection which implements IList.
IList has an insert method which allows you to insert an element at a specified index, in your case 0, here a full example:
MainPage mainPage = new MainPage();
var miniBrowser = new WebBrowser
{
Visibility = Visibility.Collapsed;
};
mainPage.Content.Children.Insert(0, miniBrowser);
I didn't add a name to the WebBrowser class since because it is being added programatically it really makes no difference (the Name property is used at design time (xaml is parsed at design time and at runtime[in the InitializeComponent method]) to generate a property in a partial class (MainPage.i.g.cs/MainPage.g.cs)).
The way you get hold of MainPage is usually from Application.Current.Content (Application.Current will contain a Frame whose Content is MainPage).

UI Page inside class library

I am developing a class library in Windows 8 (C#), in which i require to show an UI to get user input. How to create UI inside class library and invoking it. Please help.
Now I am invoking the Popup from class library to show the required UI, but I found the popup is opening from library but its hiding below the other UI element (Webview in my case).Please refer the code snippet below.
Class library code
namespace PopUpLibrary
{
public class PopupDialog
{
public void ShowPopup()
{
Popup popup = new Popup();
popup.HorizontalAlignment = HorizontalAlignment.Center;
popup.VerticalAlignment = VerticalAlignment.Center;
popup.Height = 500;
popup.Width = 700;
Button button = new Button();
button.Content = "adfadfad";
button.Width = 200;
button.Height = 100;
popup.Child = button;
popup.IsOpen = true;
}
}
}
Application code:
MainPage.xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<WebView Name="webview" ></WebView>
</Grid>
MainPage.xaml.cs
public MainPage()
{
this.InitializeComponent();
webview.Navigate(new Uri("http://www.google.com"));
PopupDialog popupdialog = new PopupDialog();
popupdialog.ShowPopup();
}
You cannot show other controls on top of the WebView. However, you can work around this by temporarily hiding the WebView and displaying a WebViewBrush.
From the WebView Documentation:
WebView has the characteristic that other UI regions such as controls cannot be rendered on top of the WebView. This is because of how window regions are handled internally, particularly how input events are processed and how the screen draws. If you want to render HTML content and also place other UI elements on top of that HTML content, you should use WebViewBrush as the render area. The WebView still provides the HTML source information, and you reference that WebView through the SourceName property. WebViewBrush does not have this overlay limitation.
If you want to display an interactive WebView that only occasionally has overlapping content (such as a drop-down list or app bar), you can temporarily hide the WebView control when necessary, replacing it with an element using a WebViewBrush fill. Then, when the overlapping content is no longer present, you can display the original WebView again. For more info, see the WebView control sample.
What kind of input? Yes/No or string input?
For Yes/No you could use the standard MessageDialog. If you need to receive custom input, such as text, you could use the CustomDialog control, available in the Callisto toolkit.