c# - example - uwp tutorial
Ocultar las elipsis dentro de una AppBar (5)
Cuando creas una AppBar o una CommandBar en una aplicación UWP, siempre hay una elipsis escondida cerca del lado del control, así:
No lo quiero en mi aplicación, pero no he encontrado ningún método / propiedad dentro de AppBar
que me ayude a deshacerme de él. Debería ser posible, porque muchas de las aplicaciones predeterminadas de Windows 10 no lo tienen. Por ejemplo, no hay elipsis en la barra de menú principal a continuación:
¿Es posible ocultar los puntos suspensivos usando AppBar
, o tengo que usar un SplitView
o algún otro control para implementar esto?
Si desea ocultar este botón globalmente, es suficiente para agregar
<Style x:Key="EllipsisButton" TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
al archivo de recursos globales
Sé que esta pregunta ya no está activa, pero a fin de completarla, estoy proponiendo mi respuesta.
En lugar de cambiar la visibilidad mediante el uso de estilos, he escrito una extensión AttachedProperty que puede ocultar / mostrar MoreButton a través del enlace de datos. De esta manera puede mostrar / ocultar condicionalmente como desee.
El uso es tan simple como vincular su propiedad a la extensión:
<CommandBar extensions:CommandBarExtensions.HideMoreButton="{Binding MyBoolean}">
...
</CommandBar>
El código de extensión es el siguiente:
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;
}
}
En el enlace inicial usa el evento Loaded para aplicar el escondite una vez que se ha cargado. FindDescendantByName
es otro método de extensión que itera el árbol visual. Es posible que desee crear o tomar uno si su solución aún no lo contiene.
Sobre la base de la respuesta de @ RadiusK (que tiene algunos problemas), se me ocurrió una alternativa que es probada y funciona:
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;
}
}
}
Como no puedo agregar un comentario a la respuesta en particular, lo publicaré aquí.
La siguiente página ofrece muchos ejemplos que encontrarán el objeto secundario para complementar la respuesta de @ RadiusK.
¿Cómo puedo encontrar los controles de WPF por nombre o tipo?
El que funcionó para mí específicamente en UWP fue:
/// <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;
}
Llamar al código de esta manera:
var morebutton = FindChild<Button>(commandBar, "MoreButton");
Primero, intente no usar AppBar
en sus nuevas aplicaciones UWP.
El control CommandBar para aplicaciones universales de Windows se ha mejorado para proporcionar un superconjunto de la funcionalidad de AppBar y una mayor flexibilidad en la forma en que puede usarlo en su aplicación. Debe usar CommandBar para todas las nuevas aplicaciones universales de Windows en Windows 10.
Puedes leer más sobre esto aquí .
Tanto CommandBar
como AppBar
pueden ser de estilo completo y plantillas. Esto le da la capacidad de eliminar los elementos de UI que no desee visualizar.
Así es como lo haces -
Abra su página en Blend, haga clic derecho en CommandBar
> Editar plantilla> Editar una copia . Luego, asegúrese de seleccionar Definir en la aplicación ya que actualmente hay un error en Mezcla que no generará los estilos si elige Este documento .
Una vez que tenga todos los estilos, busque el control MoreButton
y configure su Visibility
en Collapsed
(o puede eliminarlo, pero ¿qué MoreButton
si se da cuenta de que lo necesita más adelante?).
Entonces deberías tener una CommandBar
sin los puntos suspensivos.
Actualización para 2017 La visibilidad del botón de puntos suspensivos ahora se puede encontrar en la Propiedad OverflowButtonVisibility
de una CommandBar
. Como en el caso anterior, Collapsed
para ocultarlo.