对WPF项目控件中的最后一项使用不同的模板

Bra*_* W. 20 wpf templates itemscontrol

我在itemscontrol中使用自定义模板来显示以下结果:

item 1, item 2, item3,
Run Code Online (Sandbox Code Playgroud)

我想更改最后一项的模板,结果变为:

item 1, item2, item3
Run Code Online (Sandbox Code Playgroud)

ItemsControl:

<ItemsControl ItemsSource="{Binding Path=MyCollection}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}"/>
                <TextBlock Text=", "/>
            </StackPanel>

        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

有没有人可以为我的问题提供解决方案?谢谢!

Bra*_* W. 57

我只使用XAML找到了我的问题的解决方案.如果有人需要这样做,请使用:

<ItemsControl ItemsSource="{Binding Path=MyCollection}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            <StackPanel Orientation="Horizontal">
                <TextBlock x:Name="comma" Text=", "/>
                <TextBlock Text="{Binding}"/>
            </StackPanel>

            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
                    <Setter TargetName="comma" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>

        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

  • 作为那些来到这里寻找基于最初问题(以及其他错误链接的类似问题)答案的人的说明,这不是你想要的.此解决方案更改FIRST项目的模板,而不是最终项目模板. (28认同)
  • +1简单的解决方案.但是应该注意的是,如果对数据绑定集合(排序,过滤,添加或删除)进行任何更改,则不会再次触发"DataTrigger",并且不会相应地更新"DataTemplate". (4认同)
  • 但请注意,对于包含大量项目的控件,PreviousData结果非常慢,在1000个项目上使用它是不可用的. (2认同)

sll*_*sll 7

您可以使用DataTemplateSelector,在SelectTemplate()方法中可以检查项是否为最后一项,然后返回另一个模板.

在XAML中:

<ItemsControl.ItemTemplate>     
  <DataTemplate>
      <ContentPresenter 
             ContentTemplateSelector = "{StaticResource MyTemplateSelector}">
Run Code Online (Sandbox Code Playgroud)

在Code背后:

 private sealed class MyTemplateSelector: DataTemplateSelector
 { 

    public override DataTemplate SelectTemplate(
                                      object item, 
                                      DependencyObject container)
    {
        // ...
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 使用提供的参数(项目和容器),我无法确定项目是否是集合中的最后一个。 (2认同)

Dec*_*lor 5

此解决方案影响最后一行并随着基础集合的更改而更新:


代码隐藏

转换器需要 3 个参数才能正常运行 - 当前项目、项目控制、项目计数,如果当前项目也是最后一项,则返回 true:

  class LastItemConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int count = (int)values[2];

            if (values != null && values.Length == 3 && count>0)
            {
                System.Windows.Controls.ItemsControl itemsControl = values[0] as System.Windows.Controls.ItemsControl;
                var itemContext = (values[1] as System.Windows.Controls.ContentPresenter).DataContext;
            
                var lastItem = itemsControl.Items[count-1];

                return Equals(lastItem, itemContext);
            }

            return DependencyProperty.UnsetValue;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
Run Code Online (Sandbox Code Playgroud)

XAML

DataTemplate 的数据触发器,包括一个名为“PART_TextBox”的文本框:

  <DataTemplate.Triggers>
            <DataTrigger Value="True" >
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource LastItemConverter}">
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" />
                        <Binding RelativeSource="{RelativeSource Self}"/>
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="Items.Count"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Foreground" TargetName="PART_TextBox" Value="Red" />
            </DataTrigger>
 </DataTemplate.Triggers>      
Run Code Online (Sandbox Code Playgroud)

转换器作为 Xaml 中的静态资源

<Window.Resources>
     <local:LastItemConverter x:Key="LastItemConverter" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

快照

以及它的运行快照

在此处输入图片说明代码已从这个“代码项目” https://www.codeproject.com/Articles/242628/A-Simple-Cross-Button-for-WPF添加到项目控件中

注意最后一项的红色文字