如何在 Universal Windows Apps 8.1 中显示和隐藏文本块
How to show and hide a Text Block in Universal Windows Apps 8.1
在面向 Windows Store 8.1 和 Windows Phone 8.1 的 Windows Universal Apps 8.1 平台中,我需要隐藏一个显示 "The list is empty" 的文本块当绑定到 ListView
的集合中有一些项目时,我需要在集合为空时显示此文本块。
请提出解决方案。
到目前为止我已经试过了,但是当集合中有项目时它不起作用元素 TasksEmptyMsg 仍然显示 "The list is empty".
<Page
x:Class="ToDoer.Pages.Task"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ToDoer.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="Tasks"
ItemsSource="{Binding Tasks}"
SelectedItem="{Binding SelectedTask,Mode=TwoWay}"
ItemTemplate="{StaticResource TasksItemTemplate}"
Padding="24,24">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding TaskSelectionChanged}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ListView>
<TextBlock x:Name="TasksEmptyMsg"
Text="The list is empty"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Style="{StaticResource GroupHeaderTextBlockStyle}">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding ElementName=Tasks,Path=Items.Count}"
Value="0">
<core:ChangePropertyAction TargetObject="{Binding ElementName=TasksEmptyMsg}"
PropertyName="Visibility"
Value="Visible"/>
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBlock>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" IsHitTestVisible="False" />-->
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Icon="Add"
Label="add todo"
Command="{Binding AddTask}"/>
</CommandBar>
</Page.BottomAppBar>
</Page>
当集合中没有项目时工作正常。
问题:显示 "The list is empty",即使未显示。
ListView 本身没有任何 属性 通知它是空的,也没有绑定到 Items.Count 帮助这里,因为 属性 变化不是加注。值得庆幸的是,实现这种机制并不难,并且有几种方法可以实现。这是一个使用 Converters:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<local:BoolToVisibility x:Key="BoolToVisibility"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="TheList" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Tasks}" Visibility="{Binding IsTasksEmpty, Converter={StaticResource BoolToVisibility}, ConverterParameter='INVERT'}"/>
<TextBlock x:Name="EmptyText" Grid.Column="0" Text="List is empty" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding IsTasksEmpty, Converter={StaticResource BoolToVisibility}}"/>
<StackPanel Grid.Column="1">
<Button Content="Add item" Click="AddButton_Click" Margin="20"/>
<Button Content="Delete item" Click="DelButton_Click" Margin="20"/>
</StackPanel>
</Grid>
和后面的代码:
public class BoolToVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language) => (bool)value != ((string)parameter == "INVERT") ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); }
}
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public ObservableCollection<string> Tasks { get; set; } = new ObservableCollection<string>() { "Starting item" };
public bool IsTasksEmpty => Tasks.Count < 1;
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
Tasks.CollectionChanged += (sender, e) => RaiseProperty(nameof(IsTasksEmpty));
}
private void AddButton_Click(object sender, RoutedEventArgs e) => Tasks.Add("Next item");
private void DelButton_Click(object sender, RoutedEventArgs e) => Tasks.RemoveAt(Tasks.Count - 1);
}
这是 UWP 的一个,它使用 VisualStates 和集合更改事件(看看你的代码,我假设你是使用 ObservableCollection 用于 Tasks
)。 XAML代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ListStates">
<VisualState x:Name="ListWithItems"/>
<VisualState x:Name="ListEmpty">
<VisualState.Setters>
<Setter Target="EmptyText.Visibility" Value="Visible"/>
<Setter Target="TheList.Visibility" Value="Collapsed"/>
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsTasksEmpty}"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="TheList" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Tasks}"/>
<TextBlock x:Name="EmptyText" Grid.Column="0" Text="List is empty" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
<StackPanel Grid.Column="1">
<Button Content="Add item" Click="AddButton_Click" Margin="20"/>
<Button Content="Delete item" Click="DelButton_Click" Margin="20"/>
</StackPanel>
</Grid>
后面的代码与上面的转换器解决方案相同。
UWP 的工作示例,您将 find at GitHub。
我试图在 XAML 中解决这个问题,但到目前为止我无法做到,所以我尝试了另一种方法,即使用 BooleanToVisibilityConverter 绑定 TextBlock 的可见性 属性。
我设置了一个名为 AreTasksEmpty 的 属性,属性 通知是通过使用 MvvmLight 库完成的。
/// <summary>
/// The are tasks empty.
/// </summary>
private bool _areTasksEmpty;
/// <summary>
/// Gets or sets the are tasks empty.
/// </summary>
public bool AreTasksEmpty
{
get
{
return this._areTasksEmpty;
}
set
{
this.Set(ref this._areTasksEmpty, value);
}
}
在获取任务的方法中,我更新了 属性 AreTasksEmpty 的值,如下所示。
if (this.Tasks.Any())
{
this.AreTasksEmpty = false;
}
else
{
this.AreTasksEmpty = true;
}
在XAML中,我已经完成了对Visibility
属性的绑定,如下所示,
<TextBlock x:Name="TasksEmptyMsg"
Text="The list is empty"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="{Binding AreTasksEmpty, Converter={StaticResource BooleanToVisibilityConverter}}"
Style="{StaticResource GroupHeaderTextBlockStyle}">
</TextBlock>
在面向 Windows Store 8.1 和 Windows Phone 8.1 的 Windows Universal Apps 8.1 平台中,我需要隐藏一个显示 "The list is empty" 的文本块当绑定到 ListView
的集合中有一些项目时,我需要在集合为空时显示此文本块。
请提出解决方案。
到目前为止我已经试过了,但是当集合中有项目时它不起作用元素 TasksEmptyMsg 仍然显示 "The list is empty".
<Page
x:Class="ToDoer.Pages.Task"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ToDoer.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="Tasks"
ItemsSource="{Binding Tasks}"
SelectedItem="{Binding SelectedTask,Mode=TwoWay}"
ItemTemplate="{StaticResource TasksItemTemplate}"
Padding="24,24">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding TaskSelectionChanged}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ListView>
<TextBlock x:Name="TasksEmptyMsg"
Text="The list is empty"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Style="{StaticResource GroupHeaderTextBlockStyle}">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding ElementName=Tasks,Path=Items.Count}"
Value="0">
<core:ChangePropertyAction TargetObject="{Binding ElementName=TasksEmptyMsg}"
PropertyName="Visibility"
Value="Visible"/>
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBlock>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" IsHitTestVisible="False" />-->
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Icon="Add"
Label="add todo"
Command="{Binding AddTask}"/>
</CommandBar>
</Page.BottomAppBar>
</Page>
当集合中没有项目时工作正常。
问题:显示 "The list is empty",即使未显示。
ListView 本身没有任何 属性 通知它是空的,也没有绑定到 Items.Count 帮助这里,因为 属性 变化不是加注。值得庆幸的是,实现这种机制并不难,并且有几种方法可以实现。这是一个使用 Converters:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<local:BoolToVisibility x:Key="BoolToVisibility"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="TheList" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Tasks}" Visibility="{Binding IsTasksEmpty, Converter={StaticResource BoolToVisibility}, ConverterParameter='INVERT'}"/>
<TextBlock x:Name="EmptyText" Grid.Column="0" Text="List is empty" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding IsTasksEmpty, Converter={StaticResource BoolToVisibility}}"/>
<StackPanel Grid.Column="1">
<Button Content="Add item" Click="AddButton_Click" Margin="20"/>
<Button Content="Delete item" Click="DelButton_Click" Margin="20"/>
</StackPanel>
</Grid>
和后面的代码:
public class BoolToVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language) => (bool)value != ((string)parameter == "INVERT") ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); }
}
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public ObservableCollection<string> Tasks { get; set; } = new ObservableCollection<string>() { "Starting item" };
public bool IsTasksEmpty => Tasks.Count < 1;
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
Tasks.CollectionChanged += (sender, e) => RaiseProperty(nameof(IsTasksEmpty));
}
private void AddButton_Click(object sender, RoutedEventArgs e) => Tasks.Add("Next item");
private void DelButton_Click(object sender, RoutedEventArgs e) => Tasks.RemoveAt(Tasks.Count - 1);
}
这是 UWP 的一个,它使用 VisualStates 和集合更改事件(看看你的代码,我假设你是使用 ObservableCollection 用于 Tasks
)。 XAML代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ListStates">
<VisualState x:Name="ListWithItems"/>
<VisualState x:Name="ListEmpty">
<VisualState.Setters>
<Setter Target="EmptyText.Visibility" Value="Visible"/>
<Setter Target="TheList.Visibility" Value="Collapsed"/>
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsTasksEmpty}"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="TheList" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Tasks}"/>
<TextBlock x:Name="EmptyText" Grid.Column="0" Text="List is empty" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
<StackPanel Grid.Column="1">
<Button Content="Add item" Click="AddButton_Click" Margin="20"/>
<Button Content="Delete item" Click="DelButton_Click" Margin="20"/>
</StackPanel>
</Grid>
后面的代码与上面的转换器解决方案相同。
UWP 的工作示例,您将 find at GitHub。
我试图在 XAML 中解决这个问题,但到目前为止我无法做到,所以我尝试了另一种方法,即使用 BooleanToVisibilityConverter 绑定 TextBlock 的可见性 属性。
我设置了一个名为 AreTasksEmpty 的 属性,属性 通知是通过使用 MvvmLight 库完成的。
/// <summary>
/// The are tasks empty.
/// </summary>
private bool _areTasksEmpty;
/// <summary>
/// Gets or sets the are tasks empty.
/// </summary>
public bool AreTasksEmpty
{
get
{
return this._areTasksEmpty;
}
set
{
this.Set(ref this._areTasksEmpty, value);
}
}
在获取任务的方法中,我更新了 属性 AreTasksEmpty 的值,如下所示。
if (this.Tasks.Any())
{
this.AreTasksEmpty = false;
}
else
{
this.AreTasksEmpty = true;
}
在XAML中,我已经完成了对Visibility
属性的绑定,如下所示,
<TextBlock x:Name="TasksEmptyMsg"
Text="The list is empty"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="{Binding AreTasksEmpty, Converter={StaticResource BooleanToVisibilityConverter}}"
Style="{StaticResource GroupHeaderTextBlockStyle}">
</TextBlock>