win10 uwp 列表模板选择器

标签: uwp
2203人阅读 评论(0) 收藏 举报
分类:

本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector。

如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不同,那么可以使用 列表模板选择器 来定义自己的列表,让列表中存在不同的显示。

好啦,我们先来说下我们在什么下需要使用,其实就是当我们的数据有多样,或者对数据所在位置有要求,这时需要对不同的数据做不同处理。我分为两个不同的方向来讲,第一个方向是根据数据所在的位置不同,选择不同的显示。第二个方向是根据数据的不同。

根据数据位置

本文告诉大家如何做出下面的控件,可以看到这使用的是 ListView ,但是第一个元素显示和其他的元素不同,看起来就是面包屑导航

需要定义第一个元素和其他元素的代码,于是使用 Path 做出来,因为本文不是说如何使用 Path 所以就不多说,直接写代码。

      <DataTemplate x:Name="OtherItem">
                <StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
                    <Grid Height="30">
                        <StackPanel Orientation="Horizontal" Margin="0,0,-8,0" Height="30" >
                            <Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#000000" />
                            <Grid Margin="-1 0 0 0">
                                <Rectangle Fill="#000000" />
                                <TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
                            </Grid>
                            <Path Data="M0,0 10,15 0,30" Fill="#000000" />
                        </StackPanel>
                    </Grid>
                </StackPanel>
            </DataTemplate>
            <DataTemplate x:Name="FirstItem">
                <StackPanel x:Name="t1" Orientation="Horizontal" Margin="10 0 -12 0" Height="30">
                    <Grid Height="30">
                        <StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
                            <Grid>
                                <Rectangle Fill="#000000" />
                                <TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
                            </Grid>
                            <Path Data="M0,0 10,15 0,30" Fill="#000000" />
                        </StackPanel>
                    </Grid>
                </StackPanel>
            </DataTemplate>

然后在后台定义一个类 AvmdoicYcxhqxugnSelector ,这个可以用来选择不同的模板,于是对于第一个元素,选择第一个模板,其他的元素选择其他的模板。AvmdoicYcxhqxugnSelector需要继承DataTemplateSelector重写方法,通过重写SelectTemplateCore可以选择不同的DataTemplate,但是AvmdoicYcxhqxugnSelector需要两个属性才可以获得这两个DataTemplate所以代码很简单。

    public class AvmdoicYcxhqxugnSelector : 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;
        }
    }

然后就是创建一个 ListView 用来显示元素,还需要一个数据,于是所有的代码就是:


            <local:AvmdoicYcxhqxugnSelector x:Key="Selector" FirstItem="{StaticResource FirstItem}" OtherItem="{StaticResource OtherItem}"></local:AvmdoicYcxhqxugnSelector>
    <ListView Margin="10,10,10,10" ItemsSource="{x:Bind SkaxicIjocc}" ItemTemplateSelector="{StaticResource Selector}">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
   public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        public ObservableCollection<string> SkaxicIjocc { get; set; } = new ObservableCollection<string>()
        {
            "lindexi","csdn","cnblogs","自己博客","加班"
        };
    }

但是这样看起来还是不是我要的,把鼠标放上去,发现出现背景

如何去背景请看win10 UWP ListView

就是把ListViewItem复制,然后去掉ListViewItemBackgroundPointerOverSelectedBackground SelectedPointerOverBackground 就好了。实际把很多属性去掉就可以做出比较好的效果,但是选中的修改颜色还需要后台写。这是我修改的 Template 可以直接复制使用。

              <ListViewItemPresenter
                            ContentTransitions="{TemplateBinding ContentTransitions}"
                            SelectionCheckMarkVisualEnabled="False"
                            CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                            CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                            DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}"
                            DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
                            FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}"
                            FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}"
                            PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
                            DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
                            DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
                            ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                            HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                            ContentMargin="{TemplateBinding Padding}"
                            CheckMode="Inline"/>

下面来告诉大家使用不同的数据,如何对不同的数据有特殊显示。

根据不同的数据

例如我们做了一个类,叫做 人,这时我们继承人做出来 男生 和女生,那么男生的属性可能和女生的不同。所以需要对不同的数据有特殊的显示。

假设我们的 人 有个属性叫做名称,而男生有个属性叫身高,女孩有个属性叫年龄,当然女生年龄放出来并不好,不过我也没找到别的。这时需要显示男生的身高和女生的年龄,可以看到这时的 DataTemplate 难以按照不同的数据显示。于是接下来,我就告诉大家如何让列表显示不同的数据。

好啦,我们在ViewModel放一个ObservableCollection<Human> HumanWord,这时我们发现,在前台不好弄,如何让列表显示男生和女孩,因为他们的属性不同。

这时就需要我们做选择器,这个可以根据我们传入选择模板。

首先我们建立一个类,这个类用于选择需要显示的 DataTemplate ,名称:ListViewDataTemplateSelector 需要继承 DataTemplateSelector 。这个类需要有两个 DataTemplate 一个显示 男生,一个显示女生,其中DataTemplate会在 xaml 写,不会在 cs 写,因为在这里写难度有些高。


 public DataTemplate MaleData { set; get; }

 public DataTemplate FemaleData { set; get; }

然后我们判断我们是否传进来是男生,如果是就返回 MaleData ,女生就返回女生的DataTemplate,这时需要 override SelectTemplateCore。可以看到这个方法重载有两个,如果我们的 ItemsPanelItemsStackPanel 或 ItemsWrapGrid 我们就需要选择 SelectTemplateCore(Object) 。如果我们的 VirtualizingStackPanel 或其他的WrapGrid ,就是 SelectTemplateCore(Object, DependencyObject)。请看代码,很简单判断是男生还是女生。

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item is Male)
            {
                return MaleData;
            }
            return FemaleData;
        }

下面就是如何使用这个类,首先需要在 xaml 先写出两个 DataTemplate 。需要注意的是DataTemplate 和选择器都是资源,因为资源的获取是有顺序,所以需要先写DataTemplate,而且需要给DataTemplate一个 key 。然后在写ListViewDataTemplateSelector,把刚才写的DataTemplate放在ListViewDataTemplateSelector的属性FemaleData,MaleData 。注意ListViewDataTemplateSelector也需要key,关于资源的寻找,参见win10 uwp x:Bind 无法获得资源
一定要有key,然后在ListViewDataTemplateSelector放在FemaleData,MaleData,注意也要key,随便给个名称都好。

        <DataTemplate x:Key="MaleData">
            <Grid>
               <Border>
                   <Grid Margin="10,10,10,10">
                        <StackPanel>
                            <TextBlock Text="名称"></TextBlock>
                            <TextBlock Text="{Binding Path=Name}"></TextBlock>
                            <TextBlock Text="身高"></TextBlock>
                            <TextBlock Text="{Binding Path=Stature}"></TextBlock>
                        </StackPanel>
                    </Grid>
               </Border>
            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="FemaleData">
            <Grid>
                <Border>
                    <Grid Margin="10,10,10,10">
                        <StackPanel>
                            <TextBlock Text="名称"></TextBlock>
                            <TextBlock Text="{Binding Path=Name}"></TextBlock>
                            <TextBlock Text="年龄"></TextBlock>
                            <TextBlock Text="{Binding Path=Year}"></TextBlock>
                        </StackPanel>
                    </Grid>
                </Border>
            </Grid>
        </DataTemplate>
        <local:ListViewDataTemplateSelector x:Key="Selector" FemaleData="{StaticResource FemaleData}"
                                            MaleData="{StaticResource MaleData}"></local:ListViewDataTemplateSelector>

在需要使用的ListView就可以指定资源,相信大家也知道如何用。

        <ListView ItemsSource="{x:Bind View.HumanWorld}"
                  ItemTemplateSelector="{StaticResource Selector}"></ListView>

这里写图片描述

如果使用的数据,传入的列是男生的,那么就会使用MaleData,于是就可以对不同的数据使用不同的DataTemplate。上面的例子只是很简单使用两个不同的数据,如果有很多不同的数据,或者数据里,需要按照数据内容,进行自定义的显示,那么使用选择器也是可以做到。

源代码:https://github.com/lindexi/kechengbiao

如果需要所有源代码,请联系我因为现在csdn上传需要审查,总是无法上传

参见:win10 uwp 如何使用DataTemplate

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

查看评论

WordPress博客模板系统开发

-
  • 1970年01月01日 08:00

UWP: Win10 软件开发之学习笔记(2017.5.11更新)

现代操作系统应用开发以下是我个人的学习笔记,欢迎大家提出疑问,我们一起探讨。github1.XAML XAML只是特定格式的XML,它遵循所有XML的规则。XML的使用者就是将我们的代码变成windo...
  • linwh8
  • linwh8
  • 2017-03-22 20:02:04
  • 1780

win10 uwp 绑定密码

win10 下,密码框无法绑定到ViewModel,Password是不可以绑定。 我们可以自己使用简单方法去绑定...
  • lindexi_gd
  • lindexi_gd
  • 2017-04-28 09:06:05
  • 957

3组合框(Combo Box)和列表框(List Box)

(1)  添加组合框控件 IDC_CMB_DEMO qu
  • dongsoso
  • dongsoso
  • 2014-04-10 14:36:30
  • 954

UWP从服务器下载文件

  • 2017年08月30日 11:45
  • 2KB
  • 下载

Win10开发:ListView实现分组和索引

本篇文章讲解ListView控件的分组和索引的实现 两点说明: 1、Demo中所使用的数据源是SymbolIcon符号,MSDN链接:https://msdn.microsoft.com/zh-c...
  • zmq570235977
  • zmq570235977
  • 2015-12-23 11:28:05
  • 2177

win10 uwp 入门

UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客。...
  • lindexi_gd
  • lindexi_gd
  • 2016-07-27 08:55:57
  • 4814

win10 uwp 右击选择 GridViewItem

有时候我们需要选择一个 GridView 的一项,通过我们右击。
  • lindexi_gd
  • lindexi_gd
  • 2017-01-11 08:59:43
  • 1287

UWP写字符串到文件

  • 2017年08月30日 11:47
  • 3KB
  • 下载

UWP_WebApi发送获取数据

  • 2017年08月30日 11:43
  • 6KB
  • 下载
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 70万+
    积分: 1万+
    排名: 2168
    博客专栏
    文章分类
    最新评论