samples developing bootstrap apps app c# xaml uwp windows-10-universal

c# - developing - Cómo usar VisualState AdaptiveTrigger para cambiar ListView Item FontSize



uwp samples (2)

Estoy usando Visual State Adaptive Trigger para cambiar el aspecto de la página en función de la resolución de pantalla efectiva. Esto funciona muy bien, pero no puedo hacer que funcione para elementos ListView.

Mi ListView se ve así:

<ListView x:Name="listView" > <ListView.ItemTemplate> <DataTemplate> <TextBlock FontSize="20" Text="{Binding MyItem}"/> </DataTemplate> </ListView.ItemTemplate> </ListView>

Puedo cambiar el tamaño de la fuente TextBlock estáticamente en XAML. Pero no sé cómo hacer referencia a esto en el objetivo setter de VisualState. Al ser hijo generado automáticamente, no puedo darle un nombre a TextBlock. Mi código Visual State está debajo. He puesto ??? donde quiero referirme al elemento ListView TextBlock FontSize.

<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="NormalStateReadView"> <!-- VisualState to be triggered when window width is <720 effective pixels --> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="???" Value="20" /> </VisualState.Setters> </VisualState> </VisualStateGroup> <VisualStateGroup> <VisualState x:Name="NormalStateReadView"> <!-- VisualState to be triggered when window width is >=720 effective pixels --> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="???" Value="30" /> </VisualState.Setters> </VisualState> </VisualStateGroup>

Cualquier ayuda apreciada.


Tendrá que envolver su plantilla dentro de un UserControl para que los desencadenantes de adaptación funcionen; también los estados visuales deben ir también dentro de la plantilla y asegurarse de que estén debajo del primer elemento secundario directo (es decir, Grid ) del UserControl . Veo que ha definido dos grupos visuales de estado, pero realmente solo necesita uno.

<ListView.ItemTemplate> <DataTemplate> <UserControl> <Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="NarrowState"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="Title.(TextBlock.FontSize)" Value="24" /> </VisualState.Setters> </VisualState> <VisualState x:Name="WideState"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="Title.(TextBlock.FontSize)" Value="36" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <TextBlock x:Name="Title" Text="{Binding Property1}" /> </Grid> </UserControl> </DataTemplate> </ListView.ItemTemplate>

Actualizar

Esto es lo que creo que es una solución mucho más flexible. Necesita un poco de código para configurar, pero el resultado es que obtienes un código limpio, reutilizable y legible.

La idea es obtener una referencia del VisualStateGroup nivel superior que se define fuera de ListView , principalmente en el nivel de Page .

Luego, cree tres VisualState s (es decir, Estrecho , Normal y Ancho ) y conéctelos a un nuevo VisualStateGroup que debería pertenecer al primer elemento secundario de UserControl .

Una vez que hemos hecho referencia a estos dos VisualStateGroup , podemos monitorear el CurrentStateChanged de nivel superior y actualizar el estado en el segundo en consecuencia.

Toda la lógica anterior puede ser envuelta por un Behavior del paquete Nuget Behavior de UWP XAML .

Una vez que el Behavior en su lugar, puede definir sus estados internos tan fácil como -

<DataTemplate> <UserControl> <Interactivity:Interaction.Behaviors> <local:VisualStateInTemplateBehavior ParentVisualStateGroup="{Binding ElementName=AdaptiveVisualStates}"> <local:VisualStateInTemplateBehavior.NarrowState> <VisualState x:Name="Narrow"> <VisualState.Setters> <Setter Target="Title.(TextBlock.FontSize)" Value="24" /> </VisualState.Setters> </VisualState> </local:VisualStateInTemplateBehavior.NarrowState> <local:VisualStateInTemplateBehavior.NormalState> <VisualState x:Name="Normal"> <VisualState.Setters> <Setter Target="Title.(TextBlock.FontSize)" Value="32" /> </VisualState.Setters> </VisualState> </local:VisualStateInTemplateBehavior.NormalState> <local:VisualStateInTemplateBehavior.WideState> <VisualState x:Name="Wide"> <VisualState.Setters> <Setter Target="Title.(TextBlock.FontSize)" Value="40" /> </VisualState.Setters> </VisualState> </local:VisualStateInTemplateBehavior.WideState> </local:VisualStateInTemplateBehavior> </Interactivity:Interaction.Behaviors>

Demo de trabajo

Siéntase libre de echar un vistazo a una muestra de trabajo aquí .


No podemos usar AdaptiveTrigger para un elemento dentro de DataTemplate . Debe usar UserControl para hacerlo. Esta respuesta puede ayudarte. Si desea un video tutorial , este video puede ayudarlo. Pero tengo una pequeña solución para eso.

Aquí está mi método:

  1. Crear un TextBlock fuera de DataTemplate y establecer Visibility="Collapsed"

    <TextBlock Name="SetFontSize" Visibility="Collapsed"/>

    Nota: También puede usar BindableValueHolder lugar de esto y establecer la propiedad Value de este usando AdaptiveTrigger .

    <helpers:BindableValueHolder x:Name="SetFontSize"/>

  2. Utilice AdaptiveTrigger para cambiar el FontSize de FontSize de este TextBlock

    <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="NormalStateReadView"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="20" /> </VisualState.Setters> </VisualState> </VisualStateGroup> <VisualStateGroup> <VisualState x:Name="WideStateReadView"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="30" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>

  3. DataBind el FontSize del TextBlock dentro del DataTemplate al TextBlock externo

    <TextBlock FontSize="{Binding Path=FontSize, ElementName=SetFontSize}"/>

Aquí está tu código:

<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="NormalStateReadView"> <!-- VisualState to be triggered when window width is <720 effective pixels --> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="20" /> </VisualState.Setters> </VisualState> </VisualStateGroup> <VisualStateGroup> <VisualState x:Name="WideStateReadView"> <!-- VisualState to be triggered when window width is >=720 effective pixels --> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="30" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <TextBlock Name="SetFontSize" Visibility="Collapsed"/> <ListView x:Name="listView"> <ListView.ItemTemplate> <DataTemplate> <TextBlock FontSize="{Binding Path=FontSize, ElementName=SetFontSize}" Text="{Binding MyItem}"/> </DataTemplate> </ListView.ItemTemplate> </ListView>