Hiding the ellipsis within an AppBar
Asked Answered
L

5

16

When you create an AppBar or a CommandBar in a UWP app, there's always an ellipsis hiding near the side of the control, like so:

top right corner

I don't want it in my app but I haven't found any methods/properties within AppBarthat would help me get rid of it. It should be possible, because many of the default Windows 10 apps don't have it. For example, there's no ellipsis on the main menu bar below:

enter image description here

Is it possible to hide the ellipsis using AppBar, or do I have to use a SplitView or some other control to implement this?

Linkwork answered 3/8, 2015 at 16:4 Comment(2)
It looks like there is an ellipsis in the maps app command bar? When you click it you can select Print, Share, or Feedback. I think you are mistaken with the SplitView control. The main menu bar in this app utilizes SplitView.Rubstone
for a quick hack, I just put Padding="0,0,-48,0" to hide it.Ascospore
T
25

First, try not to use AppBar in your new UWP apps.

The CommandBar control for universal Windows apps has been improved to provide a superset of AppBar functionality and greater flexibility in how you can use it in your app. You should use CommandBar for all new universal Windows apps on Windows 10.

You can read more about it here.

Both CommandBar and AppBar can be full styled and templated. This gives you the ability to remove whatever UI elements you don't want to display.

This is how you do it -

Open your page in Blend, right click on CommandBar > Edit Template > Edit a Copy. Then make sure you select Define in Application as currently there's a bug in Blend which will fail to generate the styles if you choose This document.

Once you have all the styles, find the MoreButton control and set its Visibility to Collapsed (or you can remove it but what if you realise you need it later?).

Then you should have a CommandBar without the ellipsis.

Update for 2017 The visibility of the Ellipsis button can now be found in the OverflowButtonVisibility Property of a CommandBar. As above set it to Collapsed to hide it.

Tumbleweed answered 3/8, 2015 at 23:53 Comment(6)
I was able to hide my MoreButton. But I also want to show icon labels/app bar labels along with buttons by default. Which of the property should be changed for this?Carleycarli
@Aakansha, you can try setting this.YourCommandBar.IsOpen = true on page load but any action on the page will cause it to go collapsed again.Tumbleweed
I am getting exception when I am doing this.The exception message is "No installed components were detected. Cannot resolve TargetName HighContrastBorder."Carleycarli
I tested it and it worked fine. Maybe you should post it in a question?Tumbleweed
For those who have failed to generate the default CommandBar style in Blend. Here it is.Tumbleweed
@Carleycarli - Did you ever post this question? Couldn't find it so posted my own - #36573500 - Did you ever get this resolved? Thanks.Aboriginal
M
10

If you want to hide this button globally it enough to add

<Style x:Key="EllipsisButton" TargetType="Button">
    <Setter Property="Visibility" Value="Collapsed"/>
</Style>

to global resource file

Merchantman answered 12/11, 2015 at 9:34 Comment(1)
+1 This is also useful for modifying the style of the MoreButtonAerobatics
P
7

I know this question is is not active any more, but for sake of completion I am proposing my answer.

Instead of changing the visibility by using Styles, I have written an AttachedProperty extension that is able to hide/show the MoreButton via data binding. This way you can show/hide it conditionally as you please.

Usage is as simple as binding your property to the extension:

<CommandBar extensions:CommandBarExtensions.HideMoreButton="{Binding MyBoolean}">
    ...
</CommandBar>

The extension code is as follows:

public static class CommandBarExtensions
{
    public static readonly DependencyProperty HideMoreButtonProperty =
        DependencyProperty.RegisterAttached("HideMoreButton", typeof(bool), typeof(CommandBarExtensions), 
            new PropertyMetadata(false, OnHideMoreButtonChanged));

    public static bool GetHideMoreButton(UIElement element)
    {
        if (element == null) throw new ArgumentNullException(nameof(element));
        return (bool)element.GetValue(HideMoreButtonProperty);
    }

    public static void SetHideMoreButton(UIElement element, bool value)
    {
        if (element == null) throw new ArgumentNullException(nameof(element));
        element.SetValue(HideMoreButtonProperty, value);
    }

    private static void OnHideMoreButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var commandBar = d as CommandBar;
        if (e == null || commandBar == null || e.NewValue == null) return;
        var morebutton = commandBar.FindDescendantByName("MoreButton");
        if (morebutton != null)
        {
            var value = GetHideMoreButton(commandBar);
            morebutton.Visibility = value ? Visibility.Collapsed : Visibility.Visible;
        }
        else
        {
            commandBar.Loaded += CommandBarLoaded;
        }
    }

    private static void CommandBarLoaded(object o, object args)
    {
        var commandBar = o as CommandBar;
        var morebutton = commandBar?.FindDescendantByName("MoreButton");
        if (morebutton == null) return;
        var value = GetHideMoreButton(commandBar);
        morebutton.Visibility = value ?  Visibility.Collapsed : Visibility.Visible;
        commandBar.Loaded -= CommandBarLoaded;
    }
}

On initial binding it uses the Loaded event to apply the hiding once it has been loaded. The FindDescendantByName is another extension method that iterates the visual tree. You might want to create or grab one if your solution does not yet contain it.

Patchwork answered 8/3, 2016 at 19:14 Comment(2)
I love it, simple and easy usage.Discommode
Also, Michael Woolsay's answer contains a good child finder. (https://mcmap.net/q/714987/-hiding-the-ellipsis-within-an-appbar)Discommode
G
4

Since I cannot add a comment to the particular answer I'll post it here.

The following page gives many examples that will find the child object to compliment @RadiusK's answer.

How can I find WPF controls by name or type?

The one that worked for me specifically in UWP was:

/// <summary>
/// Finds a Child of a given item in the visual tree. 
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter. 
/// If not matching item can be found, 
/// a null parent is being returned.</returns>
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
    // Confirm parent and childName are valid. 
    if (parent == null)
        return null;

    T foundChild = null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);

        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
            // recursively drill down the tree
            foundChild = FindChild<T>(child, childName);

            // If the child is found, break so we do not overwrite the found child. 
            if (foundChild != null)
                break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
            var frameworkElement = child as FrameworkElement;

            // If the child's name is set for search
            if (frameworkElement != null && frameworkElement.Name == childName)
            {
                // if the child's name is of the request name
                foundChild = (T)child;
                break;
            }
        }
        else
        {
            // child element found.
            foundChild = (T)child;
            break;
        }
    }

    return foundChild;
}

Calling the code like this:

var morebutton = FindChild<Button>(commandBar, "MoreButton");
Gregorygregrory answered 27/6, 2016 at 13:33 Comment(0)
X
0

Building upon @RadiusK's answer (which has some issues), I came up with a conciser alternative that's tested and works:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Linq
{
    public static class CommandBarExtensions
    {
        public static readonly DependencyProperty HideMoreButtonProperty = DependencyProperty.RegisterAttached("HideMoreButton", typeof(bool), typeof(CommandBarExtensions), new PropertyMetadata(false, OnHideMoreButtonChanged));
        public static bool GetHideMoreButton(CommandBar d)
        {
            return (bool)d.GetValue(HideMoreButtonProperty);
        }
        public static void SetHideMoreButton(CommandBar d, bool value)
        {
            d.SetValue(HideMoreButtonProperty, value);
        }
        static void OnHideMoreButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var CommandBar = d as CommandBar;
            if (CommandBar != null)
            {
                var MoreButton = CommandBar.GetChild<Button>("MoreButton") as UIElement;
                if (MoreButton != null)
                {
                    MoreButton.Visibility = !(e.NewValue as bool) ? Visibility.Visible : Visibility.Collapsed;
                }
                else CommandBar.Loaded += OnCommandBarLoaded;
            }
        }

        static void OnCommandBarLoaded(object sender, RoutedEventArgs e)
        {
            var CommandBar = sender as CommandBar;

            var MoreButton = CommandBar?.GetChild<Button>("MoreButton") as UIElement;
            if (MoreButton != null)
            {
                MoreButton.Visibility = !(GetHideMoreButton(CommandBar) as bool) ? Visibility.Visible : Visibility.Collapsed;
                CommandBar.Loaded -= OnCommandBarLoaded;
            }
        }

        public static T GetChild<T>(this DependencyObject Parent, string Name) where T : DependencyObject
        {
            if (Parent != null)
            {
                for (int i = 0, Count = VisualTreeHelper.GetChildrenCount(Parent); i < Count; i++)
                {
                    var Child = VisualTreeHelper.GetChild(Parent, i);

                    var Result = Child is T && !string.IsNullOrEmpty(Name) && (Child as FrameworkElement)?.Name == Name ? Child as T : Child.GetChild<T>(Name);
                    if (Result != null)
                        return Result;
                }
            }
            return null;
        }
    }
}
Xanthine answered 12/3, 2017 at 1:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.