DragRowEventArgs.Effect Property
Gets or sets an effect available for the processed drag and drop operation.
Namespace: DevExpress.XtraVerticalGrid.Events
Assembly: DevExpress.XtraVerticalGrid.v24.1.dll
NuGet Packages: DevExpress.Win.Navigation, DevExpress.Win.VerticalGrid
Declaration
Property Value
Type | Description |
---|---|
RowDragEffect | A RowDragEffect enumeration value representing the pointer feedback indicating what happens if the mouse is released at any given moment. |
Available values:
Name | Description |
---|---|
None |
Specifies the pointer feedback indicating that none of the predefined effects is allowed for the dragged row if the mouse is released at a given moment during a drag operation. |
InsertBefore |
Specifies the pointer feedback indicating that the dragged row is allowed to be inserted before a target row if the mouse is released at a given moment during a drag operation. |
MoveChild |
Specifies the pointer feedback indicating that the dragged row is allowed to be inserted as a child of a target row if the mouse is released at a given moment during a drag operation. |
MoveToEnd |
Specifies the pointer feedback indicating that the dragged row is allowed to be inserted after the last row in the VGridControlBase.Rows collection if the mouse is released at a given moment during a drag operation. |
InsertAfter | A row is inserted after another row. |
Remarks
The Effect property is useful for providing visual feedback during a drag operation. By setting this property you can specify the icon displayed as the pointer during a drag and drop operation and enable the corresponding action for the dragged row. In this way, pointer feedback provided by this property indicates what will happen if the mouse is released at any given moment during row dragging.
In a handler for the VGridControlBase.ProcessDragRow event you can use this property to change the pointer feedback continually as the user moves the dragged row. For example, if the pointer is moved over an object that cannot accept a drop, the pointer can be changed to the “not allowed” symbol specified by the RowDragEffect.None value.
Example
This example demonstrates how you can handle native drag specific grid events in order to combine a dragged row with the targeted one in a single multi-editor row. The example implies that an editor row dragged from the Customization Form can only be dropped onto the headers of editor or multi-editor rows. In a case when the target is a multi-editor row, a dropped row is inserted as a new row item for the target row. When dropping a row onto the header cell of the targeted editor row, both rows (dropped and target) are deleted from the grid and a multi-editor row with two row items is created instead. The created row items copy base row settings from the deleted rows. The position of the drop point inside the header cell of the target row (row item) affects the index of the new row item created for the dropped row.
Note that the example uses information from the BaseViewInfo object available via the VGridControlBase.ViewInfo property in order to properly calculate the targeted header cell’s bounds. The following picture illustrates the base view info notions used in the example.
The image below displays the process of handling row drag & drop operations using the code in this example.
If you want to split a multi-editor row into several editor rows you can use the code provided by the Dragging Rows topic.
using DevExpress.XtraVerticalGrid.Rows;
using DevExpress.XtraVerticalGrid.Events;
private void vGridControl1_ProcessDragRow(object sender, DragRowEventArgs e) {
VGridControl vGrid = (sender as VGridControl);
// checking whether a row is dragged from the Customization Form
if (!((vGrid.CustomizationForm != null) && (vGrid.CustomizationForm.PressedRow != null)))
return;
// checking whether an editor row is dragged
if (!(e.Row is EditorRow)) return;
// obtaining information about a point under the mouse cursor
VGridHitInfo hitInfo = vGrid.CalcHitInfo(vGrid.PointToClient(e.ScreenLocation));
// checking whether a row is dragged over the Customization Form or over a category row
if (!((hitInfo.HitInfoType != HitInfoTypeEnum.CustomizationForm) && (hitInfo.Row != null) &&
(!(hitInfo.Row is CategoryRow)))) {
e.Effect = RowDragEffect.None;
return;
}
// obtaining specific custom information about the mouse cursor point
PointInfo pInfo = GetPointInfo(hitInfo.Row, e.ScreenLocation);
// allowing row dropping is a point belongs to target row's header
if (pInfo.IsContained) e.Effect = RowDragEffect.InsertBefore;
// restricting row dropping in the other case
else e.Effect = RowDragEffect.None;
}
private void vGridControl1_EndDragRow(object sender, EndDragRowEventArgs e) {
VGridControl vGrid = (sender as VGridControl);
// checking whether a row from the Customization Form is dropped
if (!((vGrid.CustomizationForm != null) && (vGrid.CustomizationForm.PressedRow != null)))
return;
// checking whether an editor row is dropped
if (!(e.Row is EditorRow)) return;
// obtaining information about a point under the mouse cursor
VGridHitInfo hitInfo = vGrid.CalcHitInfo(vGrid.PointToClient(e.ScreenLocation));
// checking whether a row is dropped onto the Customization Form or a category row
if (!((hitInfo.HitInfoType != HitInfoTypeEnum.CustomizationForm) &&
(hitInfo.Row != null) && (!(hitInfo.Row is CategoryRow)))) {
e.Effect = RowDragEffect.None;
return;
}
BaseRow targetRow = hitInfo.Row;
// obtaining specific custom information about the mouse cursor point
PointInfo pInfo = GetPointInfo(hitInfo.Row, e.ScreenLocation);
if (!(pInfo.IsContained)) {
// if the header rectangle does not contain the drop point,
// a drop operation is not processed
e.Effect = RowDragEffect.None;
return;
}
// specifying the cursor feedback for the processed drop operation
e.Effect = RowDragEffect.InsertBefore;
// preserving children of the dropped row from being deleted
if (e.Row.HasChildren) PreserveChildren(e.Row);
switch (targetRow.XtraRowTypeID){
case 1: // the target is an editor row
// preserving children of the target row from being deleted
if (targetRow.HasChildren) PreserveChildren(targetRow);
// substituting the dropped and target rows with a new multi-editor row
CreateMERow(e.Row, targetRow, pInfo.DroppedBefore);
break;
case 2: // the target is a multi-editor row
// inserting the dropped row as a new row item to the target multi-editor row
InsertRowItem(e.Row, (targetRow as MultiEditorRow), pInfo.RowItemIndex, pInfo.DroppedBefore);
break;
}
}
public Rectangle CalcHeaderCellRect(BaseRow row, int cellIndex){
// this function uses grid's view info to properly calculate a rectangle
// occupied by the target row header cell
VGridControl grid = row.Grid;
// obtaining the header cell rectangle of the processed row item specified by the index
Rectangle headerCellRect = (grid.ViewInfo[row].headerInfo.CaptionsInfo[cellIndex]
as RowCaptionInfo).CaptionRect;
if (cellIndex == 0){
// obtaining the number of row indent elements
int rowIndentsCount = grid.ViewInfo[row].headerInfo.RowIndents.Count;
if (rowIndentsCount != 0) {
// recalculating the rectangle for the first header cell
// since it visually comprises the last row indent element
int leftPos = grid.ViewInfo[row].headerInfo.RowIndents[rowIndentsCount - 1].Bounds.Left;
headerCellRect.Width += headerCellRect.X - leftPos;
headerCellRect.X = leftPos;
}
}
return headerCellRect;
}
public struct PointInfo {
public bool IsContained;
public int RowItemIndex;
public bool DroppedBefore;
}
public PointInfo GetPointInfo(BaseRow row, Point point){
PointInfo pInfo = new PointInfo();
// transforming screen coordinates of the cursor position to grid client ones
Point mouseClientPoint = row.Grid.PointToClient(point);
// checking whether the mouse cursor is positioned
// within a particular header cell of the processed row
for (int i = 0; i < row.RowPropertiesCount; i++){
// obtaining the header cell rectangle of the processed row item
Rectangle headerCellRect = CalcHeaderCellRect(row, i);
// checking whether the header cell rectangle contains the drop point
// collecting information about the point if it is contained in a header cell rectangle
if (headerCellRect.Contains(mouseClientPoint)) {
pInfo.IsContained = true;
// calculating the middle point of the target row's header cell
int headerCellMiddle = (headerCellRect.Left + headerCellRect.Right) / 2;
// calculating whether the dropped row should be inserted before the processed row item
pInfo.DroppedBefore = (mouseClientPoint.X < headerCellMiddle) ? true : false;
// specifying the index of the row item whose header cell contains the point
pInfo.RowItemIndex = i;
return pInfo;
}
}
// the specified point does not belong to the target row's header
pInfo.IsContained = false;
return pInfo;
}
public void PreserveChildren(BaseRow row){
// this procedure moves children of the specified row to the top-level row collection
// and hides them in the Customization Form
ArrayList rowList = new ArrayList(row.ChildRows);
foreach (BaseRow childRow in rowList){
childRow.Grid.MoveRow(childRow, childRow.Grid.Rows[0],true);
childRow.Visible = false;
}
}
public void CreateMERow (BaseRow source, BaseRow dest, bool droppedFirst){
// this procedure creates a new multi-editor row with two row items initialized
//with corresponding rows' property values
MultiEditorRow meRow = new MultiEditorRow();
MultiEditorRowProperties sourceRowItem = new MultiEditorRowProperties();
CopyProperties(source.Properties, (sourceRowItem as RowProperties));
MultiEditorRowProperties destRowItem = new MultiEditorRowProperties();
CopyProperties(dest.Properties, (destRowItem as RowProperties));
if (droppedFirst){
meRow.PropertiesCollection.Add(sourceRowItem);
meRow.PropertiesCollection.Add(destRowItem);
}
else {
meRow.PropertiesCollection.Add(destRowItem);
meRow.PropertiesCollection.Add(sourceRowItem);
}
// inserting the newly created multi-editor row to the target row's position
if (dest.ParentRow != null){
int index = dest.ParentRow.ChildRows.IndexOf(dest);
dest.ParentRow.ChildRows.Insert(meRow, index);
}
else {
int index = dest.Grid.Rows.IndexOf(dest);
dest.Grid.Rows.Insert(meRow, index);
}
// deleting an instance of the target row
dest.Dispose();
// deleting an instance of the dropped row
source.Dispose();
}
public void InsertRowItem (BaseRow source, MultiEditorRow dest, int itemIndex,
bool droppedBefore){
// this procedure creates a new row item, initializes it with the values of the dropped row
// and inserts the item at a specific position within the target row
MultiEditorRowProperties newRowItem = new MultiEditorRowProperties();
CopyProperties(source.Properties, (newRowItem as RowProperties));
if (droppedBefore) dest.PropertiesCollection.Insert(itemIndex, newRowItem);
else {
if (itemIndex == dest.PropertiesCollection.Count)
dest.PropertiesCollection.Add(newRowItem);
else
dest.PropertiesCollection.Insert(itemIndex + 1, newRowItem);
}
// deleting an instance of the dropped row
source.Dispose();
}
public void CopyProperties(RowProperties source, RowProperties dest){
// this procedure copies the public row properties of one row to another
source.AssignTo(dest);
}