【问题标题】:How to show the UWP ShellBackButton as a button in Template10?如何在 Template10 中将 UWP ShellBackButton 显示为按钮?
【发布时间】:2017-08-15 20:58:21
【问题描述】:

我需要在 Template10 的用户控件中将 UWP ShellBackButton 显示为按钮。

ShellBackButton 是应用程序左上角的后退按钮,但我需要在主屏幕中将其显示为按钮,以便用户单击它。

我对此进行了研究,但找不到如何做到这一点。

App.xaml.cs 中有一个属性来显示左上角的按钮,即ShowShellBackButton,我想在我的用户控件视图中将其作为按钮。

【问题讨论】:

    标签: c# uwp template10


    【解决方案1】:

    从 cmets 开始,我认为保留旧答案完全无关紧要。所以更新的答案如下:

    控制

    这只是控件的基本虚拟版本,您需要添加视觉状态和其他资源、资产和自定义样式,但骨架如下所示:

    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
    
    
    }
    

    创建控件后,现在您需要为其添加默认样式: 资源字典

    <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>
    

    以上是控件正常运行所需的两个必要条件。

    稍后你可以编辑资源字典来个性化控件,一旦你弄清楚了你可以冻结它,当你在其他应用程序中使用它时,你可以简单地覆盖默认样式而不是手动更改资源字典每一次。

    我希望这会有所帮助。我已经在GitGub上上传了一个模板10版本的解决方案的副本

    【讨论】:

    • 感谢 Aditya 的回复,我确实尝试了那里的示例,尤其是在覆盖内置行为部分。当我实现这个 并导航到第二页,后退按钮根本不显示。不知道是不是少了什么东西?
    • 您能否帮我快速检查一下,更改可见性,然后重新启动应用程序。不要重新部署,只需重新启动并检查它是否有效。因为如果确实如此,那么我知道问题出在哪里。否则我会做一个快速演示
    • 再次感谢您的快速回复。我确实尝试了几次更改可见性属性,但它仍然没有显示后退按钮。快速演示将非常有帮助。我这几天一直有这个问题。非常感谢。
    • 太棒了。我会做一个快速演示。它甚至不会花很长时间。你能分享一下你到底想做什么吗?就像你提到的用户控制。你提到了导航。能否请您详细说明。或者,如果您愿意,您可以分享导致代码问题的演示,我可以修复它。两者都可以
    • 我需要显示一个后退按钮,类似于上面 Template10 示例中的那个。我试图把它们放到一个用户控件中,这个按钮只是用来处理后退导航。顺便说一句,它不需要是用户控件,它只需要在单击后退按钮时将页面更新到上一个屏幕。再次感谢您。
    【解决方案2】:

    Template10 通过 Bootstrapper 提供导航服务(并通过 ViewModelBase.NavigationService 属性显示它),您可以使用它来处理按钮中的向后导航:

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

    有关 INavigationService 和引导程序的更多详细信息,请参阅 https://github.com/Windows-XAML/Template10/wiki/Bootstrapper#navigation-service

    【讨论】:

    • 嗨,吉姆,感谢您的回复。我确实按照那里的例子,github.com/Windows-XAML/Template10/wiki/Controls#navigation,但仍然无法在画布上显示后退按钮。我想知道你能指导我更具体的例子。我只想在画布上显示后退按钮,而不是在左上角。谢谢。
    • 标题栏中的后退按钮是通过模板实现的,因此您无法将其从标题栏中移动。最好的办法是在画布上添加一个按钮控件,并将按钮样式设置为您想要的样式。该按钮应该调用 INavigationService.GoBack() 方法。
    • 感谢吉姆提供的信息。实际上 Template10 具有类似于画布上的后退按钮的东西,并且导航将由 Template10 自动处理,基于此处的示例代码
      唯一的问题是我测试的时候没有工作。我导航到第 2 页,但没有显示返回按钮。
    【解决方案3】:

    最后,我得到了这个工作。如果您遇到这种情况,这里是供您将来参考的解决方案。

    以下内容需要在继承 Template10 中的 ViewModelBase 的 ViewModel 中。

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

    您还可以使用 CanGoBack 属性使后退按钮可见或不可见。

    【讨论】:

    • Template10.Mvvm.ViewModelBase 包含对您可以使用的 INavigationService 的 NavigationService 的引用。
    猜你喜欢
    • 2015-10-27
    • 2019-05-18
    • 2016-05-16
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多