Back to Devexpress

VerticalGrid as the Target of Drag and Drop

windowsforms-491-controls-and-libraries-vertical-grid-drag-and-drop-ole-drag-and-drop-verticalgrid-as-the-target-of-drag-and-drop.md

latest17.7 KB
Original Source

VerticalGrid as the Target of Drag and Drop

  • Jan 13, 2025
  • 9 minutes to read

This topic shows how to customize a vertical grid control so it can serve as a target for OLE drag and drop operations. You can use this topic’s code sample to apply styles to individual rows using drag and drop. A general overview for implementing OLE drag and drop can be found in OLE Drag and Drop Overview.

Drag Styles onto Vertical Grid Rows

The sample in this topic involves the customization of two controls. A list box control will serve as the drag and drop source, the VGridControl will accept the dragged values. Actually, this sample performs the following tasks.

  • Creates and customizes two appearances (AppearanceObject objects).
  • Adds two items to the list box control that is the drag and drop source. Item captions must be the same as appearance names.
  • Performs custom painting of items in the list box.
  • Customizes the list box to be the OLE drag and drop source. Specify item captions as the drag data.
  • Customizes the vertical grid control to be the target for OLE Drag and Drop operations. Users can drop list values only onto row headers or cells. The appearance whose name is specified by the drag data must be used to paint the target row.

The grid’s styles can be initialized together with list box control items. This can be performed in the form’s Load event handler as demonstrated in the code below. Note that the list box control’s DrawMode property is set to DrawMode.OwnerDrawVariable to force the control to use the MeasureItem and DrawItem events to specify the size of its items and paint them. Also, you need to set the vertical grid control’s AllowDrop property to true to allow drop operations.

csharp
AppearanceObject[] appearanceCollection;
private void Form1_Load(object sender, System.EventArgs e) {
   // ...
   AppearanceObject appearanceBlue = new DevExpress.Utils.AppearanceObject("Blue appearance");
   appearanceBlue.BackColor = Color.LightGray;
   appearanceBlue.ForeColor = Color.Black;
   appearanceBlue.Font = new Font(appearanceBlue.Font, FontStyle.Italic);
   AppearanceObject appearanceGreen = new DevExpress.Utils.AppearanceObject("Green appearance");
   appearanceGreen.BackColor = Color.Yellow;
   appearanceGreen.ForeColor = Color.Black;
   appearanceGreen.Font = new Font("Tahoma", 10, FontStyle.Bold);

   appearanceCollection = new DevExpress.Utils.AppearanceObject[]{appearanceBlue, appearanceGreen};

   // Initializing the list box.
   listBox1.Items.Add("Blue appearance");
   listBox1.Items.Add("Green appearance");
   listBox1.DrawMode = DrawMode.OwnerDrawVariable;
   // Enabling dropping onto the vertical grid.
   vGridControl1.AllowDrop = true;
}
vb
Dim appearanceCollection() As AppearanceObject
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   ' ...

   Dim appearanceBlue As AppearanceObject = New AppearanceObject("Blue appearance")
   appearanceBlue.BackColor = Color.LightGray
   appearanceBlue.ForeColor = Color.Black
   appearanceBlue.Font = New Font(appearanceBlue.Font, FontStyle.Italic)
   Dim appearanceGreen As AppearanceObject = New AppearanceObject("Green appearance")
   appearanceGreen.BackColor = Color.Yellow
   appearanceGreen.ForeColor = Color.Black
   appearanceGreen.Font = New Font("Tahoma", 10, FontStyle.Bold)

   appearanceCollection = New AppearanceObject() {appearanceBlue, appearanceGreen}

   ' Initializing the list box.
   ListBox1.Items.Add("Blue appearance")
   ListBox1.Items.Add("Green appearance")
   ListBox1.DrawMode = DrawMode.OwnerDrawVariable
   ' Enabling dropping onto the vertical grid.
   VGridControl1.AllowDrop = True
End Sub

The next step is to specify the size of items and paint them using the defined styles. The list box’s MeasureItem and DrawItem events are used for this purpose. The MeasureItem event handler sets the processed item’s height to the height of the “Style Sample” string if it was painted using the font set by the corresponding style. The DrawItem event handler paints the processed item using the corresponding style’s settings.

csharp
private void listBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) {
   AppearanceObject appearance = appearanceCollection[e.Index];
   e.ItemHeight = (int) e.Graphics.MeasureString("Style Sample", appearance.Font).Height;
}

private void listBox1_DrawItem(object sender, DrawItemEventArgs e) {
    AppearanceObject appearance = appearanceCollection[e.Index];
    using (SolidBrush brush = new SolidBrush(appearance.BackColor)) {
        e.Graphics.FillRectangle(brush, e.Bounds);
    }
    using (SolidBrush fbrush = new SolidBrush(appearance.ForeColor)) {
        e.Graphics.DrawString("Style Sample", appearance.Font, fbrush, e.Bounds);
    }
}
vb
Private Sub ListBox1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles ListBox1.MeasureItem
   Dim appearance As AppearanceObject = appearanceCollection(e.Index)
   e.ItemHeight = e.Graphics.MeasureString("Style Sample", appearance.Font).Height
End Sub

Private Sub ListBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ListBox1.DrawItem
    Dim appearance As AppearanceObject = appearanceCollection(e.Index)
    Using brush As SolidBrush = New SolidBrush(appearance.BackColor)
        e.Graphics.FillRectangle(brush, e.Bounds)
    End Using
    Using fbrush As SolidBrush = New SolidBrush(appearance.ForeColor)
        e.Graphics.DrawString("Style Sample", appearance.Font, fbrush, e.Bounds)
    End Using
End Sub

Now you need to customize the list box to make it the source for drag and drop operations. This will be performed in the MouseDown event handler. It will check whether the mouse cursor is currently over an item and if so, dragging will be initialized using the DoDragDrop method call. The item’s caption (that is the same as the corresponding style name) will then be passed to this method as the data to be dragged. See the code below.

csharp
private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
   ListBox lb = sender as ListBox;
   int itemIndex = lb.IndexFromPoint(e.X, e.Y);
   if (itemIndex != -1) {
      string dragData = lb.Items[itemIndex].ToString();
      lb.DoDragDrop(dragData, DragDropEffects.Copy);
   }
}
vb
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   Dim lb As ListBox = CType(sender, ListBox)
   Dim itemIndex As Integer = lb.IndexFromPoint(e.X, e.Y)
   If Not itemIndex = -1 Then
      Dim dragData As String = lb.Items(itemIndex).ToString()
      lb.DoDragDrop(dragData, DragDropEffects.Copy)
   End If
End Sub

The DragOver event handler determines whether a row header or a cell is located underneath the mouse pointer and if so, it allows the drop operation. Note that you must use the VGridControlBase.CalcHitInfo method to determine which element is at the specified point. Please refer to the Obtain Hit Information topic for details on using this method.

The code below demonstrates how the dragging process is handled.

csharp
private void vGridControl1_DragOver(object sender, System.Windows.Forms.DragEventArgs e) {
   VGridControl grid = sender as VGridControl;
   Point testPoint = grid.PointToClient(new Point(e.X, e.Y));
   VGridHitInfo hitInfo = grid.CalcHitInfo(testPoint);
   if (hitInfo.Row != null)
      e.Effect = DragDropEffects.Copy;
   else
      e.Effect = DragDropEffects.None;
}
vb
Private Sub VGridControl1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles VGridControl1.DragOver
   Dim grid As VGridControl = CType(sender, VGridControl)
   Dim testPoint As Point = grid.PointToClient(New Point(e.X, e.Y))
   Dim hitInfo As VGridHitInfo = grid.CalcHitInfo(testPoint)
   If Not hitInfo.Row Is Nothing Then
      e.Effect = DragDropEffects.Copy
   Else
      e.Effect = DragDropEffects.None
   End If
End Sub

The last thing to complete the sample is to handle dropping. This involves writing a handler for the DragDrop event of the vertical grid. The handler determines the row located underneath the mouse pointer and assigns the dragged style to it. The BaseRow.AppearanceCell property specifies row style.

csharp
private void vGridControl1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
   VGridControl grid = sender as VGridControl;
   // Obtaining the hit information.
   Point testPoint = grid.PointToClient(new Point(e.X, e.Y));
   VGridHitInfo hitInfo = grid.CalcHitInfo(testPoint);
   // Obtaining the dragged data - the appearance name.
   string styleName = e.Data.GetData(DataFormats.Text).ToString();
   // Applying the appearance settings to the row.
   AppearanceObject appearance = GetAppearanceByName(appearanceCollection, styleName);
   if(appearance != null)
      hitInfo.Row.AppearanceCell.Combine(appearance);
}
vb
Private Sub VGridControl1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles VGridControl1.DragDrop
   Dim grid As VGridControl = CType(sender, VGridControl)
   ' Obtaining the hit information.
   Dim testPoint As Point = grid.PointToClient(New Point(e.X, e.Y))
   Dim hitInfo As VGridHitInfo = grid.CalcHitInfo(testPoint)
   ' Obtaining the dragged data - the appearance name.
   Dim styleName As String = e.Data.GetData(DataFormats.Text).ToString()
   ' Applying the appearance settings to the row.
   Dim appearance As AppearanceObject = GetAppearanceByName(appearanceCollection, styleName)
   If Not appearance Is Nothing Then
      hitInfo.Row.AppearanceCell.Combine(appearance)
   End If
End Sub

Complete Code

csharp
using DevExpress.Utils;
using DevExpress.XtraVerticalGrid;

AppearanceObject[] appearanceCollection;
private void Form1_Load(object sender, System.EventArgs e) {
   // ...
   AppearanceObject appearanceBlue = new DevExpress.Utils.AppearanceObject("Blue appearance");
   appearanceBlue.BackColor = Color.LightGray;
   appearanceBlue.ForeColor = Color.Black;
   appearanceBlue.Font = new Font(appearanceBlue.Font, FontStyle.Italic);
   AppearanceObject appearanceGreen = new DevExpress.Utils.AppearanceObject("Green appearance");
   appearanceGreen.BackColor = Color.Yellow;
   appearanceGreen.ForeColor = Color.Black;
   appearanceGreen.Font = new Font("Tahoma", 10, FontStyle.Bold);

   appearanceCollection = new DevExpress.Utils.AppearanceObject[]{appearanceBlue, appearanceGreen};

   // Initializing the list box.
   listBox1.Items.Add("Blue appearance");
   listBox1.Items.Add("Green appearance");
   listBox1.DrawMode = DrawMode.OwnerDrawVariable;
   // Enabling dropping onto the vertical grid.
   vGridControl1.AllowDrop = true;
}

private void listBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) {
   AppearanceObject appearance = appearanceCollection[e.Index];
   e.ItemHeight = (int) e.Graphics.MeasureString("Style Sample", appearance.Font).Height;
}

private void listBox1_DrawItem(object sender, DrawItemEventArgs e) {
    AppearanceObject appearance = appearanceCollection[e.Index];
    using (SolidBrush brush = new SolidBrush(appearance.BackColor)) {
        e.Graphics.FillRectangle(brush, e.Bounds);
    }
    using (SolidBrush fbrush = new SolidBrush(appearance.ForeColor)) {
        e.Graphics.DrawString("Style Sample", appearance.Font, fbrush, e.Bounds);
    }
}

private AppearanceObject GetAppearanceByName(DevExpress.Utils.AppearanceObject[] collection, string appearanceName) {
   for(int i = 0; i < collection.Length; i++) {
      if(collection[i].Name == appearanceName)
         return collection[i];
   }
   return null;
}

private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
   ListBox lb = sender as ListBox;
   int itemIndex = lb.IndexFromPoint(e.X, e.Y);
   if (itemIndex != -1) {
      string dragData = lb.Items[itemIndex].ToString();
      lb.DoDragDrop(dragData, DragDropEffects.Copy);
   }
}

private void vGridControl2_DragOver(object sender, System.Windows.Forms.DragEventArgs e) {
   VGridControl grid = sender as VGridControl;
   Point testPoint = grid.PointToClient(new Point(e.X, e.Y));
   VGridHitInfo hitInfo = grid.CalcHitInfo(testPoint);
   if (hitInfo.Row != null)
      e.Effect = DragDropEffects.Copy;
   else
      e.Effect = DragDropEffects.None;
}

private void vGridControl2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
   VGridControl grid = sender as VGridControl;
   // Obtaining the hit information.
   Point testPoint = grid.PointToClient(new Point(e.X, e.Y));
   VGridHitInfo hitInfo = grid.CalcHitInfo(testPoint);
   // Obtaining the dragged data - the appearance name.
   string styleName = e.Data.GetData(DataFormats.Text).ToString();
   // Applying the appearance settings to the row.
   AppearanceObject appearance = GetAppearanceByName(appearanceCollection, styleName);
   if(appearance != null)
      hitInfo.Row.AppearanceCell.Combine(appearance);
}
vb
Imports DevExpress.Utils
Imports DevExpress.XtraVerticalGrid

Dim appearanceCollection() As AppearanceObject
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   ' ...

   Dim appearanceBlue As AppearanceObject = New AppearanceObject("Blue appearance")
   appearanceBlue.BackColor = Color.LightGray
   appearanceBlue.ForeColor = Color.Black
   appearanceBlue.Font = New Font(appearanceBlue.Font, FontStyle.Italic)
   Dim appearanceGreen As AppearanceObject = New AppearanceObject("Green appearance")
   appearanceGreen.BackColor = Color.Yellow
   appearanceGreen.ForeColor = Color.Black
   appearanceGreen.Font = New Font("Tahoma", 10, FontStyle.Bold)

   appearanceCollection = New AppearanceObject() {appearanceBlue, appearanceGreen}

   ' Initializing the list box.
   ListBox1.Items.Add("Blue appearance")
   ListBox1.Items.Add("Green appearance")
   ListBox1.DrawMode = DrawMode.OwnerDrawVariable
   ' Enabling dropping onto the vertical grid.
   VGridControl1.AllowDrop = True
End Sub

Private Sub ListBox1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles ListBox1.MeasureItem
   Dim appearance As AppearanceObject = appearanceCollection(e.Index)
   e.ItemHeight = e.Graphics.MeasureString("Style Sample", appearance.Font).Height
End Sub

Private Sub ListBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ListBox1.DrawItem
    Dim appearance As AppearanceObject = appearanceCollection(e.Index)
    Using brush As SolidBrush = New SolidBrush(appearance.BackColor)
        e.Graphics.FillRectangle(brush, e.Bounds)
    End Using
    Using fbrush As SolidBrush = New SolidBrush(appearance.ForeColor)
        e.Graphics.DrawString("Style Sample", appearance.Font, fbrush, e.Bounds)
    End Using
End Sub

Private Function GetAppearanceByName(ByVal _collection() As AppearanceObject, ByVal appearanceName As String) As AppearanceObject
   Dim i As Integer
   For i = 0 To _collection.Length - 1
      If _collection(i).Name = appearanceName Then
         Return _collection(i)
      End If
   Next i
   Return Nothing
End Function

Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   Dim lb As ListBox = CType(sender, ListBox)
   Dim itemIndex As Integer = lb.IndexFromPoint(e.X, e.Y)
   If Not itemIndex = -1 Then
      Dim dragData As String = lb.Items(itemIndex).ToString()
      lb.DoDragDrop(dragData, DragDropEffects.Copy)
   End If
End Sub

Private Sub VGridControl1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles VGridControl1.DragOver
   Dim grid As VGridControl = CType(sender, VGridControl)
   Dim testPoint As Point = grid.PointToClient(New Point(e.X, e.Y))
   Dim hitInfo As VGridHitInfo = grid.CalcHitInfo(testPoint)
   If Not hitInfo.Row Is Nothing Then
      e.Effect = DragDropEffects.Copy
   Else
      e.Effect = DragDropEffects.None
   End If
End Sub

Private Sub VGridControl1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles VGridControl1.DragDrop
   Dim grid As VGridControl = CType(sender, VGridControl)
   ' Obtaining the hit information.
   Dim testPoint As Point = grid.PointToClient(New Point(e.X, e.Y))
   Dim hitInfo As VGridHitInfo = grid.CalcHitInfo(testPoint)
   ' Obtaining the dragged data - the appearance name.
   Dim styleName As String = e.Data.GetData(DataFormats.Text).ToString()
   ' Applying the appearance settings to the row.
   Dim appearance As AppearanceObject = GetAppearanceByName(appearanceCollection, styleName)
   If Not appearance Is Nothing Then
      hitInfo.Row.AppearanceCell.Combine(appearance)
   End If
End Sub

The following animation shows the result: