UWP 重用视觉状态管理器 [英] UWP re-use visual state manager
问题描述
为什么我们没有如此简单的 UWP 响应助手?
Why don't we have such easy responsive helpers for UWP?
我在单独的 .xaml 文件中有这些样式:
I have these styles in a separate .xaml file:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Project.App.WindowsApp.Styles">
<Style x:Key="TextTitleH1" TargetType="TextBlock" >
<Setter Property="FontFamily" Value="Quicksand"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="30" />
</Style>
<Style x:Key="TextTitleH2" TargetType="TextBlock" >
<Setter Property="FontFamily" Value="Quicksand"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="24" />
</Style>
<Style x:Key="TextTitleH3" TargetType="TextBlock" >
<Setter Property="FontFamily" Value="Quicksand"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="22" />
</Style>
<Style x:Key="TextTitleH4" TargetType="TextBlock" >
<Setter Property="FontFamily" Value="Quicksand"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="TextNormal" TargetType="TextBlock" >
<Setter Property="FontFamily" Value="Quicksand"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="16" />
</Style>
</ResourceDictionary>
我有一个使用这些样式的页面(为了简单起见省略了很多代码):
I have a page using these styles (leaving out a lot of code for simplicity):
<ScrollViewer >
<Grid>
...
<StackPanel>
<TextBlock Text="{Binding Source={CustomResource Page_Dashboard_LatestImage}}" Style="{StaticResource TextTitleH4}" />
...
<TextBlock Text="{CustomResource Page_Dashboard_NoImage}" Style="{StaticResource TextNormal}"/>
<TextBlock Text="{CustomResource Page_Dashboard_LatestImage_Description}" Style="{StaticResource TextNormal}" />
...
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Source={CustomResource Page_Dashboard_TipsTitle}} Style="{StaticResource TextTitleH4}" />
...
</StackPanel>
...
</Grid>
</ScrollViewer>
现在我可以给所有这些控件一个 x:Name
并在这个页面中使用 VisualStateManager
来调整文本的大小,但我在整个过程中都使用这些文本样式应用程序,我想一次性更改它们,为不同的屏幕尺寸定义字体大小,使用简单的类似 css 的查询:
Now I could give all of those controls a x:Name
and use VisualStateManager
within this page to resize the text, but I am using these text styles throughout the entire app and I want to change them at one point, defining a fontsize for different screen sizes, using a simple css-like query:
@media only screen and (min-width: 600px) {
.TextTileH1 {
font-size: 36;
}
}
那么,我如何在 ResourceDirectory
中一般使用 VisualStateManager
一次性更改所有文本样式以适应不同的屏幕尺寸?
So how can I generically use VisualStateManager
within a ResourceDirectory
to change all text styles at once for a different screen size?
我尝试使用 这个答案,但根据我的评论,我无法成功,我试过了对 <StackPanel>
之一应用更大的边距(也给它一个应该的名字)但没有任何改变.
I have tried using this answer, but as per my comment I was not able to succeed, I've tried to apply a bigger margin to one of the <StackPanel>
's (also giving it a name like it should) but nothing changed.
推荐答案
在测试您提供的内容后 (这个答案),我修改了一些代码:
After testing what you provided (this answer), I modified some code:
public class VisualStateExtensions : DependencyObject
{
public static void SetVisualStatefromTemplate(UIElement element, DataTemplate value)
{
element.SetValue(VisualStatefromTemplateProperty, value);
}
public static DataTemplate GetVisualStatefromTemplate(UIElement element)
{
return (DataTemplate)element.GetValue(VisualStatefromTemplateProperty);
}
public static readonly DependencyProperty VisualStatefromTemplateProperty =
DependencyProperty.RegisterAttached("VisualStatefromTemplate", typeof(DataTemplate), typeof(VisualStateExtensions), new PropertyMetadata(null,new PropertyChangedCallback(VisualStatefromTemplateChanged)));
private static void VisualStatefromTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement frameworkElement)
{
var visualStateGroups = VisualStateManager.GetVisualStateGroups(frameworkElement);
if (visualStateGroups != null)
{
var template = (DataTemplate)e.NewValue;
var content = (FrameworkElement)template.LoadContent();
var groups = VisualStateManager.GetVisualStateGroups(content);
if (groups!=null && groups.Count>0)
{
var original = groups.First();
groups.Remove(original);
visualStateGroups.Add(original);
}
}
}
}
}
使用
应用程序.xaml
...
<DataTemplate x:Key="VisualStateTemplate">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup >
<VisualState x:Name="NarrowView" >
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Header.FontSize" Value="20" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Header.FontSize" Value="30" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
...
MainPage.xaml
MainPage.xaml
<Grid controls:VisualStateExtensions.VisualStatefromTemplate="{StaticResource VisualStateTemplate}">
<TextBlock x:Name="Header" Text="Hello World!"/>
</Grid>
最好的问候.
这篇关于UWP 重用视觉状态管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!