C# &引用;“拖放和复制”;对于WPF数据网格

C# &引用;“拖放和复制”;对于WPF数据网格,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,我的工作场所正在开发一个内部程序,用于构建通用的公司电子表格。我们的程序不需要太多的功能,但我们希望包括一项功能,即单击单元格,向上/向下/向左/向右拖动,然后将原始单元格的内容复制到用户选择的单元格中,就像Excel一样 我在寻找一个可靠、明确、有背景的答案方面并没有取得任何成果。我找到的最接近这方面的东西是关于在datagrid上移动行的物理位置的文章。问题的作者没有成功,报告说他们完全跳过了“拖放复制”的实现 在按照MVVM构建的应用程序中是否有合理的方法实现此功能?简单XAML-注意添加

我的工作场所正在开发一个内部程序,用于构建通用的公司电子表格。我们的程序不需要太多的功能,但我们希望包括一项功能,即单击单元格,向上/向下/向左/向右拖动,然后将原始单元格的内容复制到用户选择的单元格中,就像Excel一样

我在寻找一个可靠、明确、有背景的答案方面并没有取得任何成果。我找到的最接近这方面的东西是关于在datagrid上移动行的物理位置的文章。问题的作者没有成功,报告说他们完全跳过了“拖放复制”的实现


在按照MVVM构建的应用程序中是否有合理的方法实现此功能?

简单XAML-注意添加到数据网格中的SelectionUnit、SelectedCellsChanges和Keyup事件

    <Window x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="MyGrid" HorizontalAlignment="Left" Height="276" Margin="18,21,0,0" VerticalAlignment="Top" Width="466" SelectionUnit="Cell" SelectedCellsChanged="SelectionChanged" KeyUp="MyGrid_PreviewKeyUp"/>
    </Grid>
</Window>

一些简单的C代码:

使用系统;
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
命名空间WpfApp4
{
公共类MyItems
{
公共int Col1{get;set;}
公共int Col2{get;set;}
公共int Col3{get;set;}
公共int Col4{get;set;}
}
公共部分类主窗口:窗口
{
//为datagrid创建一个源
公共列表数据列表{get;set;}
//放置选定单元格的位置
IList DataGridSelectedCells{get;set;}
公共主窗口()
{
初始化组件();
DataContext=this;
DataList=新列表()
{
新的MyItems(){Col1=1,Col2=2,Col3=3,Col4=4},
新的MyItems(){Col1=5,Col2=6,Col3=7,Col4=8},
新的MyItems(){Col1=9,Col2=10,Col3=11,Col4=12},
新的MyItems(){Col1=13,Col2=14,Col3=15,Col4=16},
};
MyGrid.ItemsSource=数据列表;
}
私有void SelectionChanged(对象发送方,SelectedCellsChangedEventArgs e)
{
DataGridSelectedCells=MyGrid.SelectedCells;
}
私有void MyGrid_PreviewKeyUp(对象发送方,KeyEventArgs e)
{
//检查此处的键(Ctrl D、Ctrl R等)
//然后围绕数据循环查看所选内容
//根据按下的键选择方向
foreach(DataGridSelectedCells中的DataGridCellInfo d)
{//获取单元格的内容
var cellContent=d.Column.GetCellContent(d.Item);
if(cellContent!=null)
{//如果不为null,请尝试获取内容
DataGridCell dc=(DataGridCell)cellContent.Parent;
TextBlock tb=(TextBlock)dc.Content;
//在此处更改tb.Content的内容
//或转储以进行调试
Console.WriteLine(tb.Text);
}
}
}
}
}
用户可以向任何方向拖动单元格,“GridSelectedCells”将仅填充选定的单元格。使用KeyUp(或其他首选)事件允许用户复制(或使用上下文菜单实现右键单击事件),然后根据需要循环复制数据(向前或向后)

虽然这不是一个完整的解决方案,但应该让您开始。

最终解决方案

使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
命名空间Fatele.Imp.Exp.Application.Applications.Components{
公共类数据网格行为{
公共静态只读DependencyProperty NavLikeProperty=DependencyProperty.RegisterAttached(“NavLike”,
typeof(bool)、typeof(DataGridBehavior)、新UIPropertyMetadata(NavLikeChanged);
公共静态bool GetNavLike(DependencyObject obj){
返回(bool)对象获取值(NavLikeProperty);
}
公共静态void SetNavLike(DependencyObject对象,布尔值){
对象设置值(NavLikeProperty,value);
}
私有静态无效NavLikeChanged(对象oo,DependencyPropertyChangedEventArgs ee){
var odg=(DataGrid)oo;
odg.KeyUp+=KeyUp;
}
私有静态void KeyUp(对象发送方,KeyEventArgs e){
var dataGrid=发送方作为dataGrid;
if(dataGrid==null){
返回;
}
if(e.Key!=Key.LeftCtrl){
返回;
}
if(dataGrid.SelectedCells.Count<2){
返回;
}
var firstCell=dataGrid.SelectedCells.First();
var propertyInfo=firstCell.Item.GetType().GetProperty(firstCell.Column.SortMemberPath);
如果(propertyInfo==null){
返回;
}
var value1=propertyInfo.GetValue(firstCell.Item);
foreach(dataGrid中的var cellInfo.SelectedCells.Skip(1)){
var value2=propertyInfo.GetValue(cellInfo.Item);
如果(value2==null){
propertyInfo.SetValue(cellInfo.Item,value1);
}
}
}
}
}
    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;

    namespace WpfApp4
    {
        public class MyItems
        {
            public int Col1 { get; set; }
            public int Col2 { get; set; }
            public int Col3 { get; set; }
            public int Col4 { get; set; }
        }

        public partial class MainWindow : Window
        {
            // create a source for the datagrid
            public List<MyItems> DataList { get; set; }

            // somewhere to hold the selected cells
            IList<DataGridCellInfo> DataGridSelectedCells { get; set; }

            public MainWindow()
            {
                InitializeComponent();
                DataContext = this;

                DataList = new List<MyItems>()
                {
                    new MyItems() { Col1=1, Col2=2, Col3=3, Col4=4},
                    new MyItems() { Col1=5, Col2=6, Col3=7, Col4=8},
                    new MyItems() { Col1=9, Col2=10, Col3=11, Col4=12},
                    new MyItems() { Col1=13, Col2=14, Col3=15, Col4=16},
                };

                MyGrid.ItemsSource = DataList;

            }

            private void SelectionChanged(object sender, SelectedCellsChangedEventArgs e)
            {
                DataGridSelectedCells = MyGrid.SelectedCells;
            }

            private void MyGrid_PreviewKeyUp(object sender, KeyEventArgs e)
            {
                // Check your key here (Ctrl D, Ctrl R etc)                  
                // then loop around your data looking at what is selected
                // chosing the direction based on what key was pressed       
                foreach (DataGridCellInfo d in DataGridSelectedCells)
                {   // get the content of the cell           
                    var cellContent = d.Column.GetCellContent(d.Item);
                    if (cellContent != null)
                    {  // if it's not null try to get the content
                        DataGridCell dc = (DataGridCell)cellContent.Parent;
                        TextBlock tb = (TextBlock)dc.Content;

                        // Change the contents of tb.Content here
                        // or dump for debugging
                        Console.WriteLine(tb.Text);
                    }
                }
            }
        }
}