How to show the UWP ShellBackButton as a button in

2019-06-09 21:11发布

I need to show the UWP ShellBackButton as a button in my user control in Template10.

The ShellBackButton is the back button on top left in the application but I need to show this as a button in the main screen so the user can click on it.

I have researched this, but could not find how to do this.

There a property in App.xaml.cs to show the button on top left, that is ShowShellBackButton and I want to have this as a button in my user control view.

3条回答
ら.Afraid
2楼-- · 2019-06-09 21:59

As from the comments, i thought it's completely irrelevant to keep the old answer. So The updated answer is below:

The Control

This is just a basic dummy version of the control and you will need to add visual states and other resources, assets and custom styles but the skeleton would look like below:

The C#

public sealed class MyDummyControl : Control
{

    #region fields
    private const string primaryIconName = "PrimaryIcon";
    #endregion fields

    #region UIElements
    private AppBarButton PrimaryIcon;
    #endregion UIElements

    #region Events

    public event Action PrimaryButtonClicked;

    #endregion Events

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        PrimaryIcon = this.GetTemplateChild(primaryIconName) as AppBarButton;

        //in cases with c# versions lower than 6.0
        //consider replacing the null conditional check(?) with the tradional
        //if(BackRequested!=null) and 
        //the lambda's and annonymous methods with { } and methodName()
        if (PrimaryIcon != null)
            PrimaryIcon.Click += (s, args) =>
            {
                PrimaryButtonClicked?.Invoke();
            };

    }

    public MyDummyControl()
    {
        this.DefaultStyleKey = typeof(MyDummyControl);
    }

    #region Dependancy Properties


    public UIElement HeaderContent
    {
        get { return (UIElement)GetValue(HeaderContentProperty); }
        set { SetValue(HeaderContentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HeaderContent.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeaderContentProperty =
        DependencyProperty.Register("HeaderContent", typeof(UIElement), typeof(MyDummyControl), new PropertyMetadata(null));



    public bool IsPrimaryIconCompact
    {
        get { return (bool)GetValue(IsPrimaryIconCompactProperty); }
        set { SetValue(IsPrimaryIconCompactProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsPrimaryIconCompact.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsPrimaryIconCompactProperty =
        DependencyProperty.Register("IsPrimaryIconCompact", typeof(bool), typeof(MyDummyControl), new PropertyMetadata(false));




    public UIElement Content
    {
        get { return (UIElement)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Content.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(UIElement), typeof(MyDummyControl), new PropertyMetadata(null));



    public SolidColorBrush HeaderBackground
    {
        get { return (SolidColorBrush)GetValue(HeaderBackgroundProperty); }
        set { SetValue(HeaderBackgroundProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HeaderBackground.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeaderBackgroundProperty =
        DependencyProperty.Register("HeaderBackground", typeof(SolidColorBrush), typeof(MyDummyControl), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.Gray)));




    public SymbolIcon Icon
    {
        get { return (SymbolIcon)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IconProperty =
        DependencyProperty.Register("Icon", typeof(SymbolIcon), typeof(MyDummyControl), new PropertyMetadata(new SymbolIcon(Symbol.Cancel)));



    public string IconLabel
    {
        get { return (string)GetValue(IconLabelProperty); }
        set { SetValue(IconLabelProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IconLabel.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IconLabelProperty =
        DependencyProperty.Register("IconLabel", typeof(string), typeof(MyDummyControl), new PropertyMetadata(string.Empty));

    #endregion Dependancy Properties


}

Once created the Control, now you need to add the default style to it: The Resource Dictionary

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="using:ShellBackButtonDummy.Controls">

<Style TargetType="Controls:MyDummyControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Controls:MyDummyControl">
                <Grid x:Name="layoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" >

                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <Grid Name="HeaderBanner" Background="{TemplateBinding HeaderBackground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <ContentPresenter Content="{TemplateBinding HeaderContent}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
                        <AppBarButton x:Name="PrimaryIcon" Icon="{TemplateBinding Icon}" Label="{TemplateBinding IconLabel}" IsCompact="{TemplateBinding IsPrimaryIconCompact}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                    </Grid>

                    <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1"/>

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The above are the two necessary things required for the control to function properly.

Later on you can edit the resource dictionary to personalize the control and once you have it all figured out you can freeze it and when you use it in other apps, you can simply override the default style instead of manually changing the resource dictionary each time.

I hope this helps. I've uploaded a copy of a template 10 version of the solution on GitGub

查看更多
Animai°情兽
3楼-- · 2019-06-09 21:59

Finally, I got this working. Here is the solution for future reference, if you ever stuck in this situation.

The following will need to be inside your ViewModel inheriting the ViewModelBase in Template10.

var nav = Template10.Common.WindowWrapper.Current().NavigationServices.FirstOrDefault();
        var frame = nav.Frame;
        if (frame.CanGoBack)
            frame.GoBack();

You can also make it so that the back button is visible or not by using the CanGoBack property.

查看更多
甜甜的少女心
4楼-- · 2019-06-09 22:01

Template10 provides a navigation service through the Bootstrapper (and surfaces it through the ViewModelBase.NavigationService property) that you can use to handle backwards navigation in your button:

if ( NavigationService.CanGoBack ) NavigationService.GoBack();

See https://github.com/Windows-XAML/Template10/wiki/Bootstrapper#navigation-service for more details about INavigationService and the Bootstrapper.

查看更多
登录 后发表回答