从代码隐藏设置样式会使应用程序崩溃
Setting a Style from codebehind crashes the app
我有这个页面:
<Page
x:Class="My.FilesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:My"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="using:My.ViewModel" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
d:DataContext="{d:DesignInstance Type=viewmodel:FilesPageViewModel}"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<Style TargetType="ListView" x:Name="ListStyle">
<Setter Target="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</Setter.Value>
</Setter>
<Setter Target="ItemTemplate">
<Setter.Value>
<DataTemplate>
<RelativePanel HorizontalAlignment="Stretch" Padding="0, 16">
<Image RelativePanel.AlignLeftWithPanel="True"
Source="Assets/Files.png"
Width="32" Margin="16, 0"
Name="FileThumb"/>
<StackPanel Orientation="Vertical" RelativePanel.RightOf="FileThumb">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding ModifiedDate}"/>
</StackPanel>
<Button RelativePanel.AlignRightWithPanel="True" Background="Transparent">
<Image Source="Assets/icon_Less.png" Width="16" VerticalAlignment="Center"/>
</Button>
</RelativePanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListView" x:Name="GridStyle">
<Setter Target="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<controls:WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Target="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical" Width="125" >
<Image Source="Assets/Files.png" Width="115"/>
<RelativePanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Name}" RelativePanel.AlignLeftWithPanel="True" MaxWidth="96" TextWrapping="Wrap" HorizontalTextAlignment="Center"/>
<Button Background="Transparent" RelativePanel.AlignRightWithPanel="True">
<Image Source="Assets/icon_Less.png" Width="16" VerticalAlignment="Center"/>
</Button>
</RelativePanel>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<ToggleButton Name="ViewStyleToggle"
IsChecked="False" Background="Transparent"
Checked="EnableGridStyle" Unchecked="EnableListStyle"
Content="Toggle"/>
<ListView Name="FileListView" ItemsSource="{Binding Files}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
Style="{StaticResource ListStyle}"/>
</StackPanel>
</Page>
我在用户按下按钮时设置了 ListView 的样式,代码如下:
namespace My
{
public sealed partial class FilesPage : Page
{
public FilesPage()
{
this.InitializeComponent();
}
public void EnableGridStyle(object sender, RoutedEventArgs e)
{
FileListView.Style = (Style)Resources["GridStyle"];
}
public void EnableListStyle(object sender, RoutedEventArgs e)
{
FileListView.Style = (Style)Resources["ListStyle"];
}
}
}
像这样更改样式会使应用程序崩溃,并且没有有意义的堆栈跟踪。我做错了什么?
使用x:Key
,而不是x:Name
,喜欢
<Style TargetType="ListView" x:Key="ListStyle">
通常我们使用键来查找用户定义的样式,而不是名称。
ListView默认使用的ItemsPanel模板是ItemsStackPanel
,就是VirtualizingStackPanel。为了获得更高的性能,请使用 ItemsPanel 而不是您用作 GridStyle 的 ItemsPanel 模板的 WrapPanel
,并将其 Orientation property
设置为 Horizontal。
既然你想要得到想要的包装行为,你可以使用 ItemsWrapGrid
作为 ItemsPaneltempalte 来实现这个效果,这也是 VirtualizingStackPanel。
同时WrapPanel不能UI虚拟化,可能会导致渲染等问题,所以可以参考下面的代码更改GridStyle.
<Style TargetType="ListView" x:Key="GridStyle">
<Setter Target="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
……
</Style>
注意需要使用style的Key而不是Name来改变style(如x:Key="GridStyle"
) .
我有这个页面:
<Page
x:Class="My.FilesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:My"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="using:My.ViewModel" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
d:DataContext="{d:DesignInstance Type=viewmodel:FilesPageViewModel}"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<Style TargetType="ListView" x:Name="ListStyle">
<Setter Target="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</Setter.Value>
</Setter>
<Setter Target="ItemTemplate">
<Setter.Value>
<DataTemplate>
<RelativePanel HorizontalAlignment="Stretch" Padding="0, 16">
<Image RelativePanel.AlignLeftWithPanel="True"
Source="Assets/Files.png"
Width="32" Margin="16, 0"
Name="FileThumb"/>
<StackPanel Orientation="Vertical" RelativePanel.RightOf="FileThumb">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding ModifiedDate}"/>
</StackPanel>
<Button RelativePanel.AlignRightWithPanel="True" Background="Transparent">
<Image Source="Assets/icon_Less.png" Width="16" VerticalAlignment="Center"/>
</Button>
</RelativePanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListView" x:Name="GridStyle">
<Setter Target="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<controls:WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Target="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical" Width="125" >
<Image Source="Assets/Files.png" Width="115"/>
<RelativePanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Name}" RelativePanel.AlignLeftWithPanel="True" MaxWidth="96" TextWrapping="Wrap" HorizontalTextAlignment="Center"/>
<Button Background="Transparent" RelativePanel.AlignRightWithPanel="True">
<Image Source="Assets/icon_Less.png" Width="16" VerticalAlignment="Center"/>
</Button>
</RelativePanel>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<ToggleButton Name="ViewStyleToggle"
IsChecked="False" Background="Transparent"
Checked="EnableGridStyle" Unchecked="EnableListStyle"
Content="Toggle"/>
<ListView Name="FileListView" ItemsSource="{Binding Files}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
Style="{StaticResource ListStyle}"/>
</StackPanel>
</Page>
我在用户按下按钮时设置了 ListView 的样式,代码如下:
namespace My
{
public sealed partial class FilesPage : Page
{
public FilesPage()
{
this.InitializeComponent();
}
public void EnableGridStyle(object sender, RoutedEventArgs e)
{
FileListView.Style = (Style)Resources["GridStyle"];
}
public void EnableListStyle(object sender, RoutedEventArgs e)
{
FileListView.Style = (Style)Resources["ListStyle"];
}
}
}
像这样更改样式会使应用程序崩溃,并且没有有意义的堆栈跟踪。我做错了什么?
使用x:Key
,而不是x:Name
,喜欢
<Style TargetType="ListView" x:Key="ListStyle">
通常我们使用键来查找用户定义的样式,而不是名称。
ListView默认使用的ItemsPanel模板是ItemsStackPanel
,就是VirtualizingStackPanel。为了获得更高的性能,请使用 ItemsPanel 而不是您用作 GridStyle 的 ItemsPanel 模板的 WrapPanel
,并将其 Orientation property
设置为 Horizontal。
既然你想要得到想要的包装行为,你可以使用 ItemsWrapGrid
作为 ItemsPaneltempalte 来实现这个效果,这也是 VirtualizingStackPanel。
同时WrapPanel不能UI虚拟化,可能会导致渲染等问题,所以可以参考下面的代码更改GridStyle.
<Style TargetType="ListView" x:Key="GridStyle">
<Setter Target="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
……
</Style>
注意需要使用style的Key而不是Name来改变style(如x:Key="GridStyle"
) .