tutorial sizes relativepanel microsoft responsive-design windows-runtime uwp

responsive design - sizes - UWP/WinRT: ¿Cómo usar VisualState Triggers para cambiar el estilo de todos los controles de un cierto tipo?



view uwp (2)

En mi aplicación UWP, tengo una serie de AppBarButtons separados por AppBarSeparators . Cuando el tamaño de la ventana cae por debajo de cierta cantidad, quiero ocultar los AppBarSeparators para ahorrar espacio.

Intenté algo como esto, pero no funcionó:

<VisualState.Setters> <Setter Target="AppBarSeparator" Value="Collapsed"/> </VisualState.Setters>

Entiendo que no es posible AppBarSeparators cada una de las etiquetas AppBarSeparators para que pueda orientarlas directamente, ya que se generan dinámicamente como parte de un enlace.

Entonces, ¿cómo puedo ocultar todos los AppBarSeparators cuando mi ventana se reduce por debajo de un cierto tamaño?

Editar: Aquí hay una versión simplificada de mi XAML para mostrar cómo se están generando los AppBarSeparators:

<Pivot x:Name="docPivot" ItemsSource="{Binding}"> <Pivot.ItemTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0"> <AppBarButton/> <AppBarSeparator/> <AppBarButton/> <AppBarButton/> <AppBarSeparator/> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="1"> </StackPanel> </Grid> </DataTemplate> </Pivot.ItemTemplate> </Pivot>


Como hemos discutido en el comentario, sus AppBarSeparators se generan en la AppBarSeparators Pivot , cuando los controles se colocan dentro de DateTemplate , se convierten en la estructura visual de los objetos de datos, pero VisualState dirige a los controles, por lo que no puede funcionar aquí. .

Puede usar DataBinding con Converter para hacer esto, y si el tamaño de la ventana es modificable durante el tiempo de ejecución, también puede necesitar completar su clase de origen de datos con INotifyPropertyChanged Interface .

Por ejemplo aquí:

<Page.Resources> <local:BoolVisibleConverter x:Key="cvt" /> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Pivot x:Name="docPivot" ItemsSource="{x:Bind pivotlist}" SizeChanged="docPivot_SizeChanged"> <Pivot.ItemTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0"> <AppBarButton Icon="Accept" Label="Accept" /> <AppBarSeparator Visibility="{Binding WindowWidth, Converter={StaticResource cvt}}" /> <AppBarButton Icon="Cancel" Label="Cancel" /> <AppBarButton Icon="Add" Label="Add" /> <AppBarSeparator Visibility="{Binding WindowWidth, Converter={StaticResource cvt}}" /> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="1"> </StackPanel> </Grid> </DataTemplate> </Pivot.ItemTemplate> </Pivot> </Grid>

Código subyacente, utilicé el evento FrameworkElement.SizeChanged para obtener el ancho de la ventana durante el tiempo de ejecución; si solo desea hacer que el diseño sea apto para dispositivos móviles o PC la primera vez que se carga el diseño, entonces este evento no es necesario, ni es el INotifyPropertyChanged :

private ObservableCollection<MyPivotItem> pivotlist = new ObservableCollection<MyPivotItem>(); public MainPage() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { pivotlist.Clear(); pivotlist.Add(new MyPivotItem { }); pivotlist.Add(new MyPivotItem { }); pivotlist.Add(new MyPivotItem { }); pivotlist.Add(new MyPivotItem { }); } private void docPivot_SizeChanged(object sender, SizeChangedEventArgs e) { foreach (var item in docPivot.Items) { var pivotitem = item as MyPivotItem; pivotitem.WindowWidth = Window.Current.Bounds.Width; } }

La clase MyPivotItem es así:

public class MyPivotItem : INotifyPropertyChanged { public MyPivotItem() { _windowwidth = Window.Current.Bounds.Width; } private double _windowwidth; public double WindowWidth { get { return _windowwidth; } set { if (value != _windowwidth) { _windowwidth = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = "") { if (this.PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }

Y el BoolVisibleConverter es bastante simple aquí:

public class BoolVisibleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { double? width = (double?)value; if (width <= 700) return Visibility.Collapsed; return Visibility.Visible; } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }


Puede definir una propiedad de dependencia en su página:

sealed partial class Page1: Page { public static readonly DependencyProperty SeparatorVisibilityProperty = DependencyProperty.RegisterAttached("SeparatorVisibility", typeof(Visibility), typeof(Page1), new PropertyMetadata(Visibility.Visible) ); public bool SeparatorVisibility { get { return (Visibility)this.GetValue(SeparatorVisibilityProperty); } set { this.SetValue(SeparatorVisibilityProperty , value); } } .. ..

A continuación, vincule la propiedad de Visibilidad de los Separadores de AppBar a esta propiedad:

<Page ... ... x:Name="page"> .. .. <AppBarSeparator Visibility="{Binding ElementName=page, Path=SeparatorVisibility}"/> ..

A continuación, cambie la propiedad SeparatorVisibility de la página en el estado visual:

<VisualState.Setters> <Setter Target="page.SeparatorVisibility" Value="Collapsed"/> </VisualState.Setters>

El estado visual cambia la propiedad de la página, cambiará la visibilidad de AppBarSeparators ya que su propiedad Visibility está vinculada a la propiedad SeparatorVisibility de la página. No estoy seguro si es la mejor solución, es solo lo que viene a mi mente ahora.