WPF DataGrid 行拖拽实现

        DataGrid行拖拽需要我们自己去实现,我也是模仿网上例子进行改造。

        大概思路,我们需要自定义一个DataGrid的控件,然后再样式中加入一个Popup(作为被拖拽行的显示),我们要弄成所有都可以使用,就需要将Popup内容显示的模板实现自动生成,我们可以在AutoGeneratingColumn事件里实现,我是使用XMAL的方式保存所有的控件,然后赋值给我们自定义的一个DataTemplate属性。

        拖拽主要用到Drop、MouseLeftButtonDown事件。(需要将DataGird的AllowDrop设置为True)。

        伪代码(自己自行去完整):


    
        
            
        
    

       代码手敲,可能有错误,自行修改,别问我为什么手敲,我也不想。

      xxxxx为你编辑样式的控件,此段是样式里的Popup,如何编写样式?请打开Blend。Binding都是在控件类里自行添加,类型自己F12进去看属性类型。

    

int nPreviewRowIndex = -1;

Protected override void  OnPreviewMouseLeftButtonDown(System.Window.Input.MouseButtonEventArgs e)
{
    base.OnPreViewMouseLeftButtonDown(e);

    nPreviewRowIndex = UITools.GetDataGridItemCurrentRowIndex(e.GetPosition, this);
    
    if(e.GetPostion(this).X < 30) return;
    
    if(nPreviewRowIndex < 0) return;

    this.SelectedIndex = nPreviewRowIndex;

    if(this.Items[nPreviewRowIndex] == null) return;
    
    DragDropEffects dragDropEffects = DragDropEffects.Move;
    var selectItem = this.Items[nPreviewRowIndex];
    if(DragDrop.DoDragDrop(this, selectItem, dragDropEffects) != DragDropEffects.None)
    {
        this.SelectedItem = selectItem;
    }
}

prtected override void OnDrop(DragEventArgs e)
{
    base.OnDrop(e);
    this.IsPopup = false;
    int index = UITools.GetDataGridItemCurrentRowIndex(e.GetPosition, this); //获取选择的位置
    if(index < 0|| index == prevRowIndex) return;
    
    (this.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow).BorderThickness = new Thickness(0,0,0,0);

    if(index >= this.Items.Count - 1)
    {
       index = this.Items.Count - 1;
    }

     //执行换位,这里我是定义一个ICommand,这样是用MVVM的模式在ViewModel中操作数据变化
    if(DropCommand != null)
    {
       //参数根据自己需要自己设置
       DropCommand.Execute(xx);
    }  

    prevRowIndex = - 1;   
}

protected override void OnDragOver(DragEventArgs e)
{
    base.OnDragOver(e);
    int index = UITools.GetDataGridItemCurrentRowIndex(e.GetPosition, this);

    for(int i = 0; i < this.Items.Count; i++)
    {
        DataGridRow r = this.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
        if(i != index)
        {
           r.BorderBrush = new SolidColorBrush(Colors.Transparent);
           r.BorderThickness = new Thickness(0,0,0,0);
        }
        else
        {
            r.BorderBrush = new SolidColorBrush(Color.FromRgb(32, 164, 230));
            Thickness th = new Thickness(0,0,0,0);

            if(index > prevRowIndex) th = new Thickness(0,0,0,1);
            else if(index < prevRowIndex) th = new Thickness(0,1,0,0);
            r.BorderThickness = th;
        }
    }

    if(!IsPopup)
    {
       IsPopup = true;
    }

    Size popupSize = new Size(this.ActualWidth  + 110, 20 + 10);
    Point p = e.GetPosition(this);
    p.Y += 10;
    p.X += 10;
    PopupPlacementRectangle = new Rect(p, popupSize);
}

拖拽的显示(样例):

Private XElement RooXe = 
    new XElement("{http://Schemas.microsoft.com/Winfx/2006/xaml/presentation}" + "DataTemplate",
    new XAttribute("Xmlns", "http://Schemas.microsoft.com/Winfx/2006/xaml/presentation"),
        new XElement("{http://Schemas.microsoft.com/Winfx/2006/xaml/presentation}" + "TextBlock",
             new XAttribute("Text", @"{Binding" + XXX +"}"));



XmlReader xr = RootXe.CreateReader();
DataTemplate dt = XamlReader.Load(xr) as DataTemplate;

以上就是相对完整的代码了,剩下的自己去完善吧。

你可能感兴趣的:(WPF DataGrid 行拖拽实现)