zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (56)

    [源码下载]


    背水一战 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 Kits10DesignTimeCommonConfigurationNeutralUAP10.0.10586.0Genericgeneric.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(10000);
    
            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[0] as ComboBoxItem).Content.ToString());
            }
    
            private void buttonScrollDefault_Click(object sender, RoutedEventArgs e)
            {
                 listView.ScrollIntoView(Data.Skip(100).First(), ScrollIntoViewAlignment.Default);
            }
    
            private void buttonScrollLeading_Click(object sender, RoutedEventArgs e)
            {
                listView.ScrollIntoView(Data.Skip(100).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(2, 4);
                    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 = 36, 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(0, 2);
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    IfElseActivity
    Tracking_自定义跟踪服务
    CallExternalMethodActivity
    在VSS2005中建立工作流项目(1)
    入门篇(2):了解一下WF是如何运行的
    WorkflowInstance类
    写了一个例子
    一个简单的态机模式工作流演示(2)(代码与实现)
    在产品中为用户提供流程设计器
    WorkflowRuntime
  • 原文地址:https://www.cnblogs.com/webabcd/p/7078912.html
Copyright © 2011-2022 走看看