UWP XAML ListView 在 PointerOver 上嵌套 UI
UWP XAML ListView Nested UI on PointerOver
我想创建一个 ListView,其中 ListViewItems 在标签旁边有嵌套按钮,这些按钮仅在 PointerOver 上显示。这是我为此创建的 DataTemplate。我用 VisualStateManager 试过了,但没用...
所以问题是:最好的纯XAML方法是什么? (或者至少一种工作方式就足够了;))
谢谢!
<DataTemplate x:Name="aUITodoListViewDataTemplate" x:DataType="a:aTodo">
<Grid HorizontalAlignment="Stretch" PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">
<Grid.ColumnDefinitions>
<!-- creates a grid with three columns, the first so wide as needed, and the second two in a 7/1 ratio-->
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="70*" MaxWidth="500" MinWidth="100"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- First is the actual label -->
<TextBlock Text="{x:Bind Name}" Grid.Column="0" VerticalAlignment="Center" />
<!-- the middle column is for spacing -->
<!-- the last column is for the buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal" x:Name="buttonGroup">
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
</StackPanel>
<!-- The visual states -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="buttonGroup" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="buttonGroup" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
您可以通过为 ListViewItem
提供自定义控件模板来使其工作。例如:
<ListView
ItemsSource="{Binding Data, ElementName=self}"
Grid.Row="1"
SelectionChanged="OnSelectionChanged"
x:Name="listView">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid Background="Pink" x:Name="grid" DataContext="{TemplateBinding DataContext}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<ContentPresenter />
<StackPanel Grid.Column="1" Orientation="Horizontal" x:Name="buttonGroup" Visibility="Collapsed">
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="buttonGroup.Visibility" Value="Visible" />
<Setter Target="grid.Background" Value="Orange" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
对于上下文,我的玩具模型对象如下所示:
public class Data
{
public string Name { get; set; }
}
...页面本身(名为 self
)公开了以下集合 属性:
public Data[] Data { get; set; } =
{
new Data { Name = "One" },
new Data { Name = "Two" },
new Data { Name = "Three" },
};
请注意,您无法从 ControlTemplate
中绑定到您的数据模型,因此 DataTemplate
和 TextBlock
绑定到 Name
,并且 ContentPresenter
在 ControlTemplate
中。相反,如果您想使用 DataTemplate
中的 VSM,则需要以编程方式设置状态。
Here is a related post.
结果真的很难看,如下图(鼠标悬停"Two"):
我想创建一个 ListView,其中 ListViewItems 在标签旁边有嵌套按钮,这些按钮仅在 PointerOver 上显示。这是我为此创建的 DataTemplate。我用 VisualStateManager 试过了,但没用...
所以问题是:最好的纯XAML方法是什么? (或者至少一种工作方式就足够了;))
谢谢!
<DataTemplate x:Name="aUITodoListViewDataTemplate" x:DataType="a:aTodo">
<Grid HorizontalAlignment="Stretch" PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">
<Grid.ColumnDefinitions>
<!-- creates a grid with three columns, the first so wide as needed, and the second two in a 7/1 ratio-->
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="70*" MaxWidth="500" MinWidth="100"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- First is the actual label -->
<TextBlock Text="{x:Bind Name}" Grid.Column="0" VerticalAlignment="Center" />
<!-- the middle column is for spacing -->
<!-- the last column is for the buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal" x:Name="buttonGroup">
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
</StackPanel>
<!-- The visual states -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="buttonGroup" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="buttonGroup" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
您可以通过为 ListViewItem
提供自定义控件模板来使其工作。例如:
<ListView
ItemsSource="{Binding Data, ElementName=self}"
Grid.Row="1"
SelectionChanged="OnSelectionChanged"
x:Name="listView">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid Background="Pink" x:Name="grid" DataContext="{TemplateBinding DataContext}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<ContentPresenter />
<StackPanel Grid.Column="1" Orientation="Horizontal" x:Name="buttonGroup" Visibility="Collapsed">
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="buttonGroup.Visibility" Value="Visible" />
<Setter Target="grid.Background" Value="Orange" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
对于上下文,我的玩具模型对象如下所示:
public class Data
{
public string Name { get; set; }
}
...页面本身(名为 self
)公开了以下集合 属性:
public Data[] Data { get; set; } =
{
new Data { Name = "One" },
new Data { Name = "Two" },
new Data { Name = "Three" },
};
请注意,您无法从 ControlTemplate
中绑定到您的数据模型,因此 DataTemplate
和 TextBlock
绑定到 Name
,并且 ContentPresenter
在 ControlTemplate
中。相反,如果您想使用 DataTemplate
中的 VSM,则需要以编程方式设置状态。
Here is a related post.
结果真的很难看,如下图(鼠标悬停"Two"):