Xaml 列表框和应用程序栏:最后一个元素填充

Xaml 列表框和应用程序栏:最后一个元素填充,xaml,windows-phone-7,windows-phone-8,Xaml,Windows Phone 7,Windows Phone 8,我有一个ListBox和ApplicationBar的Opacity=.5。我希望ListBox项目位于ApplicationBar下。 相似的数字: 但当我滚动到列表末尾时,ListBox的最后一个元素在ApplicationBar下 我希望最后一个元素结束ApplicationBar 我可以为列表框(LongListSelector)的最后一个元素添加填充吗?如何解决这个问题 更新 <ListBox Name="MyListBox">

我有一个
ListBox
ApplicationBar
Opacity=.5
。我希望
ListBox
项目位于
ApplicationBar
下。 相似的数字:

但当我滚动到列表末尾时,
ListBox
的最后一个元素在
ApplicationBar

我希望最后一个元素结束
ApplicationBar

我可以为
列表框
LongListSelector
)的最后一个元素添加填充吗?如何解决这个问题

更新

    <ListBox Name="MyListBox">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <i:Interaction.Triggers>
                        <ec:DataTrigger Binding="{Binding RelativeSource=
                                              {RelativeSource Self},
                                              Converter={StaticResource IsLastItemInContainerConverter}}"
                             Value="True">
                            <ec:ChangePropertyAction PropertyName="Padding" Value="0,0,0,72"/>
                        </ec:DataTrigger>
                    </i:Interaction.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Background="Red" 
                                Width="400"
                                Height="120"
                                Margin="15">                            
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>              
        </ListBox>

更新2


使用
LongListSelector
可以轻松解决我的问题。只需添加空的
ListFooterTemplate
,高度=
ApplicationBar
高度。

您可以
使用转换器检查它是否是列表框中的最后一项
,如果是,则通过DataTrigger将
填充设置为所需值

检查我的答案是否有转换器代码。为了这个答案的完整性,我将在这里发布转换器代码:

public class IsLastItemInContainerConverter : IValueConverter
{
   public object Convert(object value, Type targetType,
                         object parameter, CultureInfo culture)
   {
       DependencyObject item = (DependencyObject)value;
       ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);

       return ic.ItemContainerGenerator.IndexFromContainer(item)
               == ic.Items.Count - 1;
   }

   public object ConvertBack(object value, Type targetType,
                             object parameter, CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}
然后像这样使用它:

    <ListBox>
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource=
                                                  {RelativeSource Self},
                      Converter={StaticResource IsLastItemInContainerConverter}}"
                                 Value="True">
                        <Setter Property="Padding" Value="5"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

您可以
使用转换器检查它是否是列表框中的最后一项
,如果是,则通过数据触发器将
填充设置为所需值

检查我的答案是否有转换器代码。为了这个答案的完整性,我将在这里发布转换器代码:

public class IsLastItemInContainerConverter : IValueConverter
{
   public object Convert(object value, Type targetType,
                         object parameter, CultureInfo culture)
   {
       DependencyObject item = (DependencyObject)value;
       ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);

       return ic.ItemContainerGenerator.IndexFromContainer(item)
               == ic.Items.Count - 1;
   }

   public object ConvertBack(object value, Type targetType,
                             object parameter, CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}
然后像这样使用它:

    <ListBox>
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource=
                                                  {RelativeSource Self},
                      Converter={StaticResource IsLastItemInContainerConverter}}"
                                 Value="True">
                        <Setter Property="Padding" Value="5"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

编辑:未看到原始问题的更新。以下内容保留以获取更多详细信息

此解决方案仅适用于Windows Phone 8(但如果您的目标是7.1/5,则可以使用Windows Phone工具包中的LongListSelector)

我将用SDK中的LongListSelector替换ListBox

<Grid>
    <controls:LongListSelector ItemTemplate="{StaticResource Item}" ListFooterTemplate="{StaticResource Footer}" />
</Grid>

对于模板,添加

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="Item">
       <StackPanel Background="Red" 
                   Width="400"
                   Height="120"
                   Margin="15">                            
       </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="Footer">
        <Border Height="72" />
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

编辑:未看到原始问题的更新。以下内容保留以获取更多详细信息

此解决方案仅适用于Windows Phone 8(但如果您的目标是7.1/5,则可以使用Windows Phone工具包中的LongListSelector)

我将用SDK中的LongListSelector替换ListBox

<Grid>
    <controls:LongListSelector ItemTemplate="{StaticResource Item}" ListFooterTemplate="{StaticResource Footer}" />
</Grid>

对于模板,添加

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="Item">
       <StackPanel Background="Red" 
                   Width="400"
                   Height="120"
                   Margin="15">                            
       </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="Footer">
        <Border Height="72" />
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

最简单的解决方案可能是自定义ListBox上的ItemsPanel属性:

<ListBox>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Margin="0,0,0,150"/> <!-- set margin to show some 'blank' space after last item -->
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    ...
</ListBox>

...

但请注意,默认情况下,ListBox将VirtualizedStackPanel用作ItemsPanel。如果将其更改为StackPanel,可能会带来一些性能损失。此解决方案适用于项目较少的列表。

最简单的解决方案可能是自定义ListBox上的ItemsPanel属性:

<ListBox>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Margin="0,0,0,150"/> <!-- set margin to show some 'blank' space after last item -->
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    ...
</ListBox>

...

但请注意,默认情况下,ListBox将VirtualizedStackPanel用作ItemsPanel。如果将其更改为StackPanel,可能会带来一些性能损失。这是一种适用于项目较少的列表的解决方案。

您是否尝试过将填充/边距应用于
列表框本身?是的,如果添加到列表框边距=0,0,0,72,则所有列表框元素都位于AppBar上方。但我需要指出的是,只有最后一个元素位于应用程序栏上方。对列表框进行填充如何?您是否尝试过将填充/边距应用于
listbox
本身?是的,如果add to listbox margin=0,0,0,72,则所有列表框元素都位于AppBar上方。但我需要指出的是,只有最后一个元素位于应用程序栏上方。填充到listbox如何?我尝试了此操作,但在转换器行“return ic.ItemContainerGenerator.IndexFromContainer(item)==ic.Items.Count-1;”ic=null:(如果
ic
为空,可以使用附带的调试器进行检查吗?我检查了它,更新了帖子并添加了xaml,我在列表框中做的一切都是正确的?代码似乎是正确的。但我有一个问题-为什么要使用交互触发器?为什么不直接在Style.triggers下使用DataTrigger?RelativeSource只有Self和TemplatedParent模式。我将尝试其他选项,非常感谢!我尝试了这个,但在转换器行“return ic.ItemContainerGenerator.IndexFromContainer(item)==ic.Items.Count-1;”ic=null:(如果
ic
为空,可以使用附带的调试器进行检查吗?我检查了它,更新了帖子并添加了xaml,我在列表框中做的一切都是正确的?代码似乎是正确的。但我有一个问题-为什么要使用交互触发器?为什么不直接在Style.triggers下使用DataTrigger?RelativeSource只有Self和TemplatedParent模式。我会尝试其他选择,非常感谢!