[源码下载]

背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项

作者:webabcd

介绍
背水一战 Windows 10 之 控件(集合类 - ListViewBase)

  • 基础知识
  • 拖动项

示例
1、ListViewBase 的基础知识
Controls/CollectionControl/ListViewBaseDemo/ListViewBaseDemo1.xaml

<Page
x:Class="Windows10.Controls.CollectionControl.ListViewBaseDemo.ListViewBaseDemo1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.CollectionControl.ListViewBaseDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:common="using:Windows10.Common"> <Grid Background="Transparent">
<Grid Margin="10 0 10 10"> <StackPanel Orientation="Vertical"> <TextBlock Name="lblMsg1" />
<TextBlock Name="lblMsg2" Margin="0 10 0 0" /> <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0 10 0 0">
<CheckBox Name="chkIsItemClickEnabled" Content="IsItemClickEnabled" Margin="10 0 0 0" />
<CheckBox Name="chkShowsScrollingPlaceholders" Content="ShowsScrollingPlaceholders" Margin="10 0 0 0" />
<CheckBox Name="chkIsMultiSelectCheckBoxEnabled" Content="IsMultiSelectCheckBoxEnabled" Margin="10 0 0 0" />
<ComboBox Name="cmbSelectionMode" PlaceholderText="SelectionMode" SelectionChanged="cmbSelectionMode_SelectionChanged" Margin="10 0 0 0">
<ComboBoxItem>None</ComboBoxItem>
<ComboBoxItem>Single</ComboBoxItem>
<ComboBoxItem>Multiple</ComboBoxItem>
<ComboBoxItem>Extended</ComboBoxItem>
</ComboBox>
</StackPanel> <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0 10 0 0">
<Button Name="buttonScrollDefault" Content="滚动到第 101 条数据 ScrollIntoViewAlignment.Default" Click="buttonScrollDefault_Click" />
<Button Name="buttonScrollLeading" Content="滚动到第 101 条数据 ScrollIntoViewAlignment.Leading" Click="buttonScrollLeading_Click" Margin="10 0 0 0" />
<Button Name="buttonSelect" Content="选中第 3 到第 6 项" Click="buttonSelect_Click" Margin="10 0 0 0" />
</StackPanel>
</StackPanel> <!--
ListViewBase(基类) - 列表控件基类
Header, HeaderTemplate, Footer, HeaderTransitions - 顾名思义,不用解释
HeaderTransitions - header 的过渡效果
FooterTransitions - footer 的过渡效果
IsItemClickEnabled - 点击 item 时是否会触发 ItemClick 事件(默认值为 false)
IsSwipeEnabled - 是否支持 swipe 操作(对于 ListView 来说,在触摸模式下,左右轻扫 item 称之为 swipe; 对于 GridView 来说,在触摸模式下,上下轻扫 item 称之为 swipe)
注:经测试,在 uwp 中这个属性无效(不支持 item 的 swipe 了)
SelectionMode - item 的选中模式
None - 不能被选中
Single - 只能单选(默认值)
Multiple - 支持多选,且支持辅助键多选(ctrl 或 shift)
Extended - 支持多选,且支持辅助键多选(ctrl 或 shift)
IsMultiSelectCheckBoxEnabled - 在 SelectionMode 为 Multiple 时,是否为每个 item 显示复选框
ShowsScrollingPlaceholders - 在大数据量滚动时,为了保证流畅,是否每次显示 item 时先显示占位符(尚不清楚怎么修改这个占位符的背景色),然后再绘制内容
可以用 GridView 来呈现大量数据,以便查看滚动时 ShowsScrollingPlaceholders 带来的效果 ItemClick - 单击 item 时触发的事件(IsItemClickEnabled 为 false 时不会触发这个事件)
SelectionChanged - 选中项发生变化时触发的事件(这个来自 Selector 类,SelectionMode 为 None 时不会触发这个事件)
ContainerContentChanging - 数据虚拟化时,项容器的内容发生变化时触发的事件(仅 ItemsStackPanel 和 ItemsWrapGrid 有效)
ChoosingItemContainer - 数据虚拟化时,为项选择容器时触发的事件(仅 ItemsStackPanel 和 ItemsWrapGrid 有效)
ChoosingGroupHeaderContainer - 为每组的 header 选择容器时触发的事件(关于数据分组请参见 /Controls/CollectionControl/ItemsControlDemo/ItemsControlDemo4.xaml) 注:
1、ListViewBase 的滚动来自其内的 ScrollViewer 控件,可以通过对应的附加属性和静态方法对其设置。关于 ScrollViewer 请参见:/Controls/ScrollViewerDemo/
2、ListView 的 ItemContainer 是 ListViewItem,如果需要设置 item 的选中样式之类的就设置 ItemContainerStyle 即可
关于 ListView 的默认 ItemContainerStyle 请参见 C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10586.0\Generic\generic.xaml 中的 ListViewItemExpanded,需要修改的话请在此基础上修改
-->
<ListView x:Name="listView" VerticalAlignment="Top" HorizontalAlignment="Left" ItemsSource="{x:Bind Data}" Margin="0 150 10 10"
ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto"
SelectionMode="Single"
IsItemClickEnabled="{Binding IsChecked, ElementName=chkIsItemClickEnabled}"
ShowsScrollingPlaceholders ="{Binding IsChecked, ElementName=chkShowsScrollingPlaceholders}"
IsMultiSelectCheckBoxEnabled="{Binding IsChecked, ElementName=chkIsMultiSelectCheckBoxEnabled}"
SelectionChanged="listView_SelectionChanged"
ItemClick="listView_ItemClick">
<ListView.ItemTemplate>
<DataTemplate x:DataType="common:Employee">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name, Mode=TwoWay}" />
<TextBlock Text="{x:Bind Age, Mode=TwoWay}" Margin="10 0 0 0" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.HeaderTemplate>
<DataTemplate>
<TextBlock Text="header" />
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.HeaderTransitions>
<TransitionCollection>
<EntranceThemeTransition FromHorizontalOffset="100" />
</TransitionCollection>
</ListView.HeaderTransitions>
<ListView.FooterTemplate>
<DataTemplate>
<TextBlock Text="footer" />
</DataTemplate>
</ListView.FooterTemplate>
<ListView.FooterTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</ListView.FooterTransitions>
</ListView> </Grid>
</Grid>
</Page>

Controls/CollectionControl/ListViewBaseDemo/ListViewBaseDemo1.xaml.cs

/*
* ListViewBase(基类) - 列表控件基类(继承自 Selector, 请参见 /Controls/SelectionControl/SelectorDemo.xaml)
* SelectedItems - 被选中的 items 集合(只读)
* SelectedRanges - 被选中的 items 的范围(只读)
* SelectAll() - 选中全部 items
* SelectRange(ItemIndexRange itemIndexRange) - 选中指定范围的 items
* DeselectRange(ItemIndexRange itemIndexRange) - 取消选中指定范围的 items
* ScrollIntoView(object item, ScrollIntoViewAlignment alignment) - 滚动到指定的 item
* ScrollIntoViewAlignment.Default - 不好解释,请自己看演示效果
* ScrollIntoViewAlignment.Leading - 不好解释,请自己看演示效果
*
* ItemIndexRange - items 的范围
* FirstIndex - 范围的第一个 item 的索引位置
* LastIndex - 范围的最后一个 item 的索引位置
* Length - 范围的长度
*
*
* 注:
* ListViewBase 实现了 ISemanticZoomInformation 接口,所以可以在 SemanticZoom 的两个视图间有关联地切换。关于 ISemanticZoomInformation 请参见 /Controls/CollectionControl/SemanticZoomDemo/ISemanticZoomInformationDemo.xaml
*
*
* 本例用于演示 ListViewBase 的基础知识
*/ using System;
using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using System.Linq;
using Windows10.Common;
using Windows.UI.Xaml;
using Windows.UI.Popups; namespace Windows10.Controls.CollectionControl.ListViewBaseDemo
{
public sealed partial class ListViewBaseDemo1 : Page
{
public ObservableCollection<Employee> Data { get; set; } = TestData.GetEmployees(); public ListViewBaseDemo1()
{
this.InitializeComponent();
} // 单击行为的事件
private void listView_ItemClick(object sender, ItemClickEventArgs e)
{
// 获取被单击的 item 的数据
lblMsg1.Text = "被单击的 employee 的 name 为:" + (e.ClickedItem as Employee).Name;
} // 选中行为的事件
private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// e.RemovedItems - 本次事件中,被取消选中的项
// e.AddedItems - 本次事件中,新被选中的项 lblMsg2.Text = $"新被选中的 item 共 {e.AddedItems.Count.ToString()} 条, 新被取消选中的 item 共 {e.RemovedItems.Count.ToString()} 条";
} private void cmbSelectionMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
listView.SelectionMode = (ListViewSelectionMode)Enum.Parse(typeof(ListViewSelectionMode), (e.AddedItems[] as ComboBoxItem).Content.ToString());
} private void buttonScrollDefault_Click(object sender, RoutedEventArgs e)
{
listView.ScrollIntoView(Data.Skip().First(), ScrollIntoViewAlignment.Default);
} private void buttonScrollLeading_Click(object sender, RoutedEventArgs e)
{
listView.ScrollIntoView(Data.Skip().First(), ScrollIntoViewAlignment.Leading);
} private async void buttonSelect_Click(object sender, RoutedEventArgs e)
{
if (listView.SelectionMode == ListViewSelectionMode.Multiple || listView.SelectionMode == ListViewSelectionMode.Extended)
{
// 选中第 3, 4, 5, 6 项
ItemIndexRange iir = new ItemIndexRange(, );
listView.SelectRange(iir);
}
else
{
MessageDialog messageDialog = new MessageDialog("SelectionMode 必须是 Multiple 或 Extended", "提示");
await messageDialog.ShowAsync();
}
}
}
}

2、ListViewBase 内拖动 item
Controls/CollectionControl/ListViewBaseDemo/ListViewBaseDemo2.xaml

<Page
x:Class="Windows10.Controls.CollectionControl.ListViewBaseDemo.ListViewBaseDemo2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.CollectionControl.ListViewBaseDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:common="using:Windows10.Common"> <Page.Resources>
<DataTemplate x:Key="ItemTemplate" x:DataType="common:Employee">
<StackPanel Background="Orange" Width="100">
<TextBlock TextWrapping="Wrap" Text="{x:Bind Name}" HorizontalAlignment="Left" />
<TextBlock TextWrapping="Wrap" Text="{x:Bind Age}" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</Page.Resources> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <Button Name="buttonMove" Content="通过 api 将 gridView1 中的第 1 项数据移动到第 3 项数据的位置" Click="buttonMove_Click" Margin="0 0 0 10" /> <!--
ListViewBase(基类) - 列表控件基类
CanDragItems - item 是否可被拖动
CanReorderItems - 是否可通过拖动 item 来排序
如果设置为 true 的话,则除了在 UI 上可以拖动排序外,排序后的结果也会同步到数据源(可以通过 ObservableCollection<T> 的 CollectionChanged 事件捕获到)
AllowDrop - 是否可在 ListViewBase 中 drop(来自 UIElement)
ReorderMode - 经测试,无效
DragItemsStarting - 开始 item 拖动时触发的事件
DragItemsCompleted - 完成 item 拖动时触发的事件
--> <!--
在内部拖动可以排序,可以拖动到 gridView2 以复制,可以拖动到 borderDelete 以删除
-->
<GridView Name="gridView1" Margin="5" VerticalAlignment="Top" Height="100" ItemsSource="{x:Bind Data1}" Background="White"
ItemTemplate="{StaticResource ItemTemplate}"
CanDragItems="True" CanReorderItems="True" AllowDrop="True"
DragItemsStarting="gridView_DragItemsStarting"
DragItemsCompleted="gridView_DragItemsCompleted" /> <!--
在内部拖动可以排序,可以拖动到 borderDelete 以删除
-->
<GridView Name="gridView2" Margin="5" VerticalAlignment="Top" Height="100" ItemsSource="{x:Bind Data2}" Background="White"
ItemTemplate="{StaticResource ItemTemplate}"
CanDragItems="True" CanReorderItems="True" AllowDrop="True"
DragItemsStarting="gridView_DragItemsStarting"
DragItemsCompleted="gridView_DragItemsCompleted"
DragEnter="gridView2_DragEnter"
Drop="gridView2_Drop"/> <!--
可以拖动到 gridView2 以复制
-->
<TextBlock Name="lblEmployee" Margin="5" Foreground="Orange" Text="{x:Bind Path=Employee.Name}"
PointerPressed="lblEmployee_PointerPressed" DragStarting="lblEmployee_DragStarting" /> <!--
拖动 gridView1 或 gridView2 中的 item 到此处以删除
-->
<Border Name="borderDelete" Margin="5" Width="300" Height="100" BorderThickness="1" BorderBrush="Red" Background="Blue"
AllowDrop="True" Drop="borderDelete_Drop" DragEnter="borderDelete_DragEnter" DragLeave="borderDelete_DragLeave" DragOver="borderDelete_DragOver">
<TextBlock FontSize="32" Text="拖动到此处以删除" TextAlignment="Center" VerticalAlignment="Center" />
</Border> <TextBlock Name="lblMsg" Margin="5" Text="通过拖动 GirdView 中的 Item 进行排序" /> </StackPanel>
</Grid>
</Page>

Controls/CollectionControl/ListViewBaseDemo/ListViewBaseDemo2.xaml.cs

/*
* ListViewBase(基类) - 列表控件基类(继承自 Selector, 请参见 /Controls/SelectionControl/SelectorDemo.xaml)
*
*
* DragItemsStartingEventArgs
* Items - 被拖动的 items 集合
* Cancel - 是否取消拖动操作
* Data - 一个 DataPackage 类型的对象,用于传递数据
*
* DragItemsCompletedEventArgs
* DropResult - drop 的结果(None, Copy, Move, Link)
* Items - 被拖动的 items 集合
*
*
* 注:
* 1、drag-drop 传递数据,剪切板传递数据,分享传递数据,以及其他场景的数据传递均通过 DataPackage 类型的对象来完成
* 2、本例通过一个私有字段传递数据,通过 DataPackage 传递数据请参见:/Controls/BaseControl/UIElementDemo/DragDropDemo.xaml
* 3、关于 UIElement 拖放的详细说明请参见:/Controls/BaseControl/UIElementDemo/DragDropDemo.xaml
*
*
* 本例用于演示如何在 ListViewBase 内拖动 item 以对 item 排序,以及如何拖动 item 到 ListViewBase 外的指定位置以删除 item,以及如何拖动一个 UIElement 到 ListViewBase 内以添加这个 item
*/ using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;
using System.Linq;
using Windows.UI.Xaml;
using System.Diagnostics;
using Windows10.Common;
using Windows.ApplicationModel.DataTransfer;
using System.Collections.Specialized;
using System;
using Windows.UI.Xaml.Input; namespace Windows10.Controls.CollectionControl.ListViewBaseDemo
{
public sealed partial class ListViewBaseDemo2 : Page
{
// gridView1 的数据源
public ObservableCollection<Employee> Data1 { get; set; } = new ObservableCollection<Employee>(TestData.GetEmployees());
// gridView2 的数据源
public ObservableCollection<Employee> Data2 { get; set; } = new ObservableCollection<Employee>(); // lblEmployee 的数据源
public Employee Employee { get; set; } = new Employee() { Name = "wanglei", Age = , IsMale = true }; // 拖动中的 Employee 对象
private Employee _draggingEmployee; public ListViewBaseDemo2()
{
this.InitializeComponent(); // 这个用来证明在 gridView1 中拖动 item 排序时,其结果会同步到数据源
Data1.CollectionChanged += Data1_CollectionChanged;
} private void Data1_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
lblMsg.Text += Environment.NewLine;
lblMsg.Text += $"Action: {e.Action}, OldStartingIndex: {e.OldStartingIndex}, NewStartingIndex: {e.NewStartingIndex}";
} // 开始 item 拖动
private void gridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
_draggingEmployee = e.Items.First() as Employee;
} // 完成 item 拖动
private void gridView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
lblMsg.Text += Environment.NewLine;
lblMsg.Text += $"DropResult: {args.DropResult}"; _draggingEmployee = null;
} // item 被拖进了 borderDelete
private void borderDelete_DragEnter(object sender, DragEventArgs e)
{
// 关于 DragEventArgs 的详细介绍,以及其他属于 UIElement 拖放方面的详细介绍请参见:/Controls/BaseControl/UIElementDemo/DragDropDemo.xaml e.AcceptedOperation = DataPackageOperation.Move; e.DragUIOverride.IsGlyphVisible = false;
e.DragUIOverride.Caption = "松开则删除"; Debug.WriteLine("DragEnter");
} // item 被 drop 到了 borderDelete
private void borderDelete_Drop(object sender, DragEventArgs e)
{
// 从数据源中删除指定的 Employee 对象
Data1.Remove(_draggingEmployee);
Data2.Remove(_draggingEmployee); _draggingEmployee = null; // 在 borderDelete 放下了拖动项
Debug.WriteLine("Drop");
} // item 被拖出了 borderDelete
private void borderDelete_DragLeave(object sender, DragEventArgs e)
{
Debug.WriteLine("DragLeave");
} // item 在 borderDelete 上面拖动着
private void borderDelete_DragOver(object sender, DragEventArgs e)
{
Debug.WriteLine("DragOver");
} // item 被拖进了 gridView2
private void gridView2_DragEnter(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
} // item 被 drop 到了 gridView2
private void gridView2_Drop(object sender, DragEventArgs e)
{
Data2.Add(_draggingEmployee);
} // lblEmployee 被按下了
private async void lblEmployee_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// 启动 lblEmployee 的拖动操作
await lblEmployee.StartDragAsync(e.GetCurrentPoint(lblEmployee));
} // lblEmployee 开始被拖动
private void lblEmployee_DragStarting(UIElement sender, DragStartingEventArgs args)
{
args.Data.RequestedOperation = DataPackageOperation.Copy; _draggingEmployee = Employee;
} // 通过 api 将 gridView1 中的第 1 项数据移动到第 3 项数据的位置
private void buttonMove_Click(object sender, RoutedEventArgs e)
{
// 利用数据源 ObservableCollection 的 Move 方法
Data1.Move(, );
}
}
}

OK
[源码下载]

最新文章

  1. virtualenvwrapper安装使用
  2. HBM内存介绍
  3. 一道数学题 hduacm 5144
  4. HeadFirst jsp 02 (体系结构)
  5. Java Set接口
  6. hdu 1863 畅通工程(最小生成树,基础)
  7. 1.ssh访问限制
  8. Nodejs加密php解密
  9. OpenSSL使用指南
  10. BZOJ 1264 基因匹配Match(LCS转化LIS)
  11. 关于java.sql.SQLRecoverableException: Closed Connection异常的解决方案(转)
  12. 使用Jquery UI 高仿百度搜索下拉列表功能
  13. IIS express 7.5 配置和多网站执行
  14. CNS数据库网站只用mysql自带的fulltext index功能就可实现了。
  15. 深入理解JavaScript的this指向问题
  16. HTTP状态码表
  17. Java Number &amp; Math 类
  18. Java链表和递归
  19. Caffe源码中math_functions文件分析
  20. jq+download+文件夹下载

热门文章

  1. jvm gc 算法
  2. 对团队项目的NABCD的分析
  3. sql相同项求和
  4. 2018.11.03 NOIP模拟 图(bfs/最短路)
  5. 定时调度系列之Quartz.Net详解(转)
  6. 轮询、中断、DMA和通道
  7. Linux无法解析gitlib的地址--修改dns
  8. IntelliJ IDEA 2017版 spring-boot 2.0.5 邮件发送简单实例 (三)
  9. IntelliJ IDEA 2017版 spring-boot2.0.4+mybatis 自动部署的细节问题
  10. PageInfo 前台分页js,带分页栏