C# 在绑定的ListView中使用VisualStateGroup
我在UWP中有一个绑定的listview,我想根据一些属性在ItemTemplate中显示或隐藏一些控件 我使用的XAML在这里用于绑定ObservableCollectionC# 在绑定的ListView中使用VisualStateGroup,c#,xaml,win-universal-app,uwp,C#,Xaml,Win Universal App,Uwp,我在UWP中有一个绑定的listview,我想根据一些属性在ItemTemplate中显示或隐藏一些控件 我使用的XAML在这里用于绑定ObservableCollection <ListView x:Name="lvwMovieWatchlist" ItemsSource="{x:Bind Books}" Margin="10"> <ListView.ItemsPanel> <ItemsPanelTe
<ListView x:Name="lvwMovieWatchlist" ItemsSource="{x:Bind Books}" Margin="10">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:BookModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Width="156" Height="200">
<Image Source="{Binding CoverImage}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap" Margin="9.6,0"/>
<TextBlock Text="{Binding Name}" Style="{StaticResource SubtitleTextBlockStyle}" TextWrapping="NoWrap" Margin="9.6,0"/>
<StackPanel Orientation="Horizontal" Margin="10">
<Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click"> DOWNLOAD</Button>
<Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click"> READ</Button>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
下载
阅读
这里有两个按钮Btn_Download和Btn_Read
如果Status属性为“read”,那么我想将Btn\u read的可见性设置为可见,否则显示Btn\u下载按钮
在WPF中,我有实现相同目标的触发器
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Status}" Value="read">
<Setter TargetName="Btn_Read" Property="Visibility" Value="Visible"/>
<Setter TargetName="Btn_Download" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
但在UWP中没有触发器,只有VisualStateManager.VisualStateGroups可用。
那么,如何在ItemTemplate中使用VisualStateGroup呢?一个可能的想法是使用转换器而不是VisualStateManager:
<StackPanel Orientation="Horizontal" Margin="10">
<Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click" Visibility={Binding Status, Converter={StaticResource StatusToDownloadVisibilityConverter}}> DOWNLOAD</Button>
<Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click" Visibility={Binding Status, Converter={StaticResource StatusToReadVisibilityConverter}}> READ</Button>
</StackPanel>
下载
阅读
只需创建两个转换器(StatusToDownloadVisibilityConverter和StatusToReadVisibilityConverter),它们根据Status属性的值获取Status in参数并返回可见性
也许不是100%理想的解决方案,但这应该是可行的 如果您想完全在XAML中完成,可以使用扩展来完成。使用可视状态和datatriggeraction的示例可以如下所示-XAML:
背后的代码:
公共密封部分类主页面:第页,INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
public void RaiseProperty(字符串名称)=>PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
私有字符串status=“notRead”;
公共字符串状态
{
获取{返回状态;}
set{status=value;RaiseProperty(nameof(status));}
}
公共主页()
{
this.InitializeComponent();
DataContext=this;
}
私有无效按钮\u单击(对象发送者,路由目标e)=>Status=“读取”;
}
单击按钮可更改状态以读取并通过行为触发视觉状态更改。您可以对项目模板执行类似的操作。作为旁注,您还可以使用其他操作,根据您想要实现的目标,这些操作可能更容易一些-例如ChangePropertyAction
当然,要使其工作,您必须在项目中添加对行为的引用(添加引用->通用窗口->扩展),或者使用NuGet,诸如此类,这是一个更好的选择(开源和针对UWP)。将模板包装在用户控件中,并添加可视化状态管理器
<ListView x:Name="lvwMovieWatchlist" ItemsSource="{x:Bind ViewModel.Books}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:BookModel">
<local:BookControl />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<UserControl
x:Class="App2.BookControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ButtonsVisibility">
<VisualState x:Name="ButtonsVisible">
</VisualState>
<VisualState x:Name="ButtonsHidden">
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding Status, Mode=OneWay}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Btn_Download.Visibility" Value="Collapsed" />
<Setter Target="Btn_Read.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Subtitle}" />
<StackPanel Orientation="Horizontal">
<Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click">DOWNLOAD</Button>
<Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click">READ</Button>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
下载
阅读
此示例在布尔属性上使用内置StateTrigger。要将属性与您想要的某个值进行比较,请使用awesome WindowsStateTriggers库()中的EqualStateTrigger。可以,但我喜欢使用VisualState,因为它可以完全控制xaml本身,想要了解VisualState的概念,我只想补充一点,最好通过Nuget添加Behaviors SDK,因为它现在的目标是UWP,并且是开源的。