Loading

WPF 可拖动的ListView

这是一个很简单的程序,致力于快速打开 exe 执行文件,方便删除与新增,同时还可以拖拽 listviewitem 进行更新优先级

用途

  • 书签
  • 笔记
  • 歌单
  • 排班

支持功能

  • 批量多选
  • 打开执行程序
  • 删除列表
  • 保存状态
  • 拖动效果
  • xml 读取与更新
# 读取xml文件
        public void Read()
        {
            Task.Factory.StartNew(() =>
            {
                XmlDocument xml = new XmlDocument();
                xml.Load(Path.Combine(baseDir, "Data.xml"));
                var Item = xml.SelectSingleNode("exeTer");
                XmlNodeList node = Item.ChildNodes;
                foreach (XmlNode item in node)
                {
                    XmlElement _xml = (XmlElement)item;
                    var _path = _xml.GetAttribute("Path");
                    var _fileName = _xml.GetAttribute("FileName");
                    var _xmlmodel = new List<Exeter>();
                    App.Current.Dispatcher.InvokeAsync(() =>
                    {
                        ExeterItems.Add(new Exeter()
                        {
                            Path = _path,
                            FileName = _fileName,
                        });
                    });

                }
            });

        }
# 保存和更新
        private void SaveUpdate(List<Exeter> exeters)
        {
            List<Exeter> _list = new List<Exeter>();
            XmlDocument xml = new XmlDocument();
            var xmlpath = Path.Combine(baseDir, "Data.xml");
            xml.Load(xmlpath);
            var Item = xml.SelectSingleNode("exeTer");
            var length = Item.ChildNodes.Count;
            for (int i = length - 1; i >= 0; i--)
            {
                XmlElement _xml = (XmlElement)Item.ChildNodes[i];
                var _fileName = _xml.GetAttribute("FileName");
                var ishas = exeters.Any(p => p.FileName == _fileName);
                if (ishas)
                {
                    Item.RemoveChild(_xml);
                }
            }

            foreach (var item in exeters)
            {
                XmlElement unit = xml.CreateElement("AUnit");
                unit.SetAttribute("Path", item.Path);
                unit.SetAttribute("FileName", item.FileName);
                Item.AppendChild(unit);
            }
            xml.Save(xmlpath);
        }

在 Microsoft.Xaml.Behaviors.Wp 扩展中使用了 InvokeCommandAction

         <ToggleButton
                x:Name="tgBtn"
                Width="120"
                Height="30"
                Content="{Binding CheckName}"
                IsChecked="False">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Checked">
                        <i:InvokeCommandAction Command="{Binding OpenDropCmd}" />
                    </i:EventTrigger>
                    <i:EventTrigger EventName="Unchecked">
                        <i:InvokeCommandAction Command="{Binding CloseDropCmd}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </ToggleButton>

拖动效果

            <ListView
                x:Name="exelist"
                AllowDrop="True"
                ItemsSource="{Binding ExeterItems}"
                PreviewDragEnter="Exelist_DragEnter"
                PreviewDragLeave="Exelist_DragLeave"
                PreviewDrop="Exelist_Drop"
                PreviewMouseDown="Exelist_PreviewMouseDown"
                PreviewQueryContinueDrag="Exelist_QueryContinueDrag"
                ScrollViewer.VerticalScrollBarVisibility="Visible"
                Style="{StaticResource Bauble.Styles.ListView}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid ToolTip="{Binding Path}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="auto" />
                                <ColumnDefinition Width="auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock
                                VerticalAlignment="Center"
                                FontSize="20"
                                Foreground="White"
                                Text="{Binding FileName}" />
                            <Button
                                Grid.Column="1"
                                Width="50"
                                Margin="5"
                                Command="{Binding DataContext.OpenCmd, RelativeSource={RelativeSource AncestorType={x:Type ListView}, Mode=FindAncestor}}"
                                CommandParameter="{Binding}"
                                Content="打开" />
                            <Button
                                Grid.Column="2"
                                Width="50"
                                Margin="0,0,5,0"
                                Command="{Binding DataContext.DeletedCmd, RelativeSource={RelativeSource AncestorType={x:Type ListView}, Mode=FindAncestor}}"
                                CommandParameter="{Binding}"
                                Content="删除" />
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        private void Exelist_DragLeave(object sender, DragEventArgs e)
        {
            if (tgBtn.IsChecked == true)
            {
                e.Effects = DragDropEffects.None;
                Point pos = e.GetPosition(exelist);
                HitTestResult result = VisualTreeHelper.HitTest(exelist, pos);
                if (result == null)
                    return;

                ListViewItem selectedItem = VisualObjectHelper.FindVisualParent<ListViewItem>(result.VisualHit);
                if (selectedItem != null)
                    selectedItem.IsSelected = false;
            }
        }
        private void Exelist_DragEnter(object sender, DragEventArgs e)
        {
            if (tgBtn.IsChecked == true)
            {
                e.Effects = DragDropEffects.Copy;

                Point pos = e.GetPosition(exelist);
                HitTestResult result = VisualTreeHelper.HitTest(exelist, pos);
                if (result == null)
                    return;

                ListViewItem selectedItem = VisualObjectHelper.FindVisualParent<ListViewItem>(result.VisualHit);
                if (selectedItem != null)
                    selectedItem.IsSelected = true;
            }

        }
# 持续拖动,不停的更新
        private void Exelist_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            if (mAdornerLayer == null)
                return;

            System.Diagnostics.Debug.WriteLine($"Exelist_QueryContinueDrag {DateTime.Now.ToString("HH-mm-ss fff")}");
            mAdornerLayer.Update();
        }
# 切换到拖动模式下,阻止隧道模式向内传递事件
        private void Exelist_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (tgBtn.IsChecked == true)
            {
                e.Handled = true;

                if (e.LeftButton != MouseButtonState.Pressed)
                    return;

                Point pos = e.GetPosition(exelist);
                HitTestResult result = VisualTreeHelper.HitTest(exelist, pos);
                if (result == null)
                    return;


                ListViewItem treeViewItem = VisualObjectHelper.FindVisualParent<ListViewItem>(result.VisualHit); // Find your actual visual you want to drag
                if (treeViewItem == null || treeViewItem.DataContext == null)
                    return;

                //if ((treeViewItem.DataContext as Exeter)?.ItemList.Count > 0)
                //    return;

                Exeter dataItem = treeViewItem.DataContext as Exeter;
                if (string.IsNullOrEmpty(dataItem.FileName) || !Path.HasExtension(dataItem.Path))
                    return;

                DragDropAdorner adorner = new DragDropAdorner(treeViewItem);
                mAdornerLayer = AdornerLayer.GetAdornerLayer(exelist);
                mAdornerLayer.Add(adorner);

                DataObject dataObject = new DataObject(dataItem);
                //DoDragDrop 会处理 Exelist_DragLeave 和 Exelist_DragEnter
                DragDrop.DoDragDrop(exelist, dataObject, DragDropEffects.Copy);

                mAdornerLayer?.Remove(adorner);
                mAdornerLayer = null;
            }
        }
posted @ 2022-01-07 20:03  androllen  阅读(910)  评论(0编辑  收藏  举报