如何使 xaml ListView 中的第一项不同?
How can I make the first item in a xaml ListView different?
这是一个通用 Windows 应用程序。
请问如何只修改ListView的第一个元素?我尝试使用 header 模板,但我不知道如何将它绑定到我的步骤列表中的第一个元素。
第一个元素与其他元素之间的唯一区别是第一个边的形状是直的。第一个元素不会有这样的样式:Data="M0,0 10,0 10,30 0,30 10,15"
更新:我使用模板选择器 (DataTemplateSelector) 使其正常工作。这意味着我必须给每个项目一个位置编号。非常感谢任何更好的解决方案!
这是我的 XAML:
<Page
x:Class="CloserCrumbs.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CloserCrumbs"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.DataContext>
<local:SuperVM />
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding Steps}" SelectedItem="{Binding Steps.SelectedItem, Mode=TwoWay}" Height="40" FocusVisualPrimaryThickness="0" FocusVisualSecondaryThickness="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding ShortDescription}" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
你在这里使用的最佳选择是DataTemplateSelector
。您可以获得要应用模板的项目的索引,并对其应用特定的 DataTemplate
。
所以在这种情况下你需要 2 DataTemplates
。首先没有箭头(第一个项目)和所有其他项目的第二个。您可以在 Page
上的 Page.Resources
中添加它们。所以在这种情况下,它类似于下面。
<Page.Resources>
<DataTemplate x:Name="OtherItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="FirstItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</Page.Resources>
如果您注意到 FirstItem
DataTemplate
不包含第一个路径,使其看起来像一个起始箭头。
下面是DataTemplateSelector
的代码
public class ItemsDataTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstItem { get; set; }
public DataTemplate OtherItem { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
return (itemsControl.IndexFromContainer(container) == 0) ? FirstItem : OtherItem;
}
}
在上面的代码中,我要说的是如果索引是 0
然后应用 FirstItem
DataTemplate
否则 OtherItem
.
现在像下面这样更改您的 ListView。
<ListView x:Name="listView" VerticalAlignment="Top">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplateSelector>
<local:ItemsDataTemplateSelector FirstItem="{StaticResource FirstItem}"
OtherItem="{StaticResource OtherItem}" />
</ListView.ItemTemplateSelector>
</ListView>
这里我在选择器中分配 DataTemplates 以将 FirstItem
分配给列表中的第一个项目,其他人将获得 OtherItem
模板。
下面是临时数据的输出。
希望对您有所帮助
祝你好运。
这是一个通用 Windows 应用程序。
请问如何只修改ListView的第一个元素?我尝试使用 header 模板,但我不知道如何将它绑定到我的步骤列表中的第一个元素。
第一个元素与其他元素之间的唯一区别是第一个边的形状是直的。第一个元素不会有这样的样式:Data="M0,0 10,0 10,30 0,30 10,15"
更新:我使用模板选择器 (DataTemplateSelector) 使其正常工作。这意味着我必须给每个项目一个位置编号。非常感谢任何更好的解决方案!
这是我的 XAML:
<Page
x:Class="CloserCrumbs.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CloserCrumbs"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.DataContext>
<local:SuperVM />
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding Steps}" SelectedItem="{Binding Steps.SelectedItem, Mode=TwoWay}" Height="40" FocusVisualPrimaryThickness="0" FocusVisualSecondaryThickness="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding ShortDescription}" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
你在这里使用的最佳选择是DataTemplateSelector
。您可以获得要应用模板的项目的索引,并对其应用特定的 DataTemplate
。
所以在这种情况下你需要 2 DataTemplates
。首先没有箭头(第一个项目)和所有其他项目的第二个。您可以在 Page
上的 Page.Resources
中添加它们。所以在这种情况下,它类似于下面。
<Page.Resources>
<DataTemplate x:Name="OtherItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="FirstItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</Page.Resources>
如果您注意到 FirstItem
DataTemplate
不包含第一个路径,使其看起来像一个起始箭头。
下面是DataTemplateSelector
public class ItemsDataTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstItem { get; set; }
public DataTemplate OtherItem { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
return (itemsControl.IndexFromContainer(container) == 0) ? FirstItem : OtherItem;
}
}
在上面的代码中,我要说的是如果索引是 0
然后应用 FirstItem
DataTemplate
否则 OtherItem
.
现在像下面这样更改您的 ListView。
<ListView x:Name="listView" VerticalAlignment="Top">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplateSelector>
<local:ItemsDataTemplateSelector FirstItem="{StaticResource FirstItem}"
OtherItem="{StaticResource OtherItem}" />
</ListView.ItemTemplateSelector>
</ListView>
这里我在选择器中分配 DataTemplates 以将 FirstItem
分配给列表中的第一个项目,其他人将获得 OtherItem
模板。
下面是临时数据的输出。
希望对您有所帮助
祝你好运。