Active Query Builder support area

How to add an object to the query by dragging from external control to the query builder?

Last modified:


Preparing the right object to drop on the Design Pane

The easiest way to implement drag-n-drop from a specific external control is to initiate the drag in the following way, so the component will handle dropping automatically.

private void flowLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
{
    var orders = queryBuilder1.MetadataContainer.FindItem("Sales.SalesOrderHeader");
    var metadataDragObject = new MetadataDragObject { MetadataDragged = { orders } };
    flowLayoutPanel1.DoDragDrop(metadataDragObject, DragDropEffects.Move | DragDropEffects.Copy);
}

Note that you should initiate the MetadataDragObject using MetadataItem objects from the component's own Metadata Container. Otherwise, you'll see the block icon on hover.

Allowing to drop generic text objects on Design Pane

If you want to let drop generic objects to the Design Pane from arbitrary external controls, you should handle the appropriate events of the DesignPane (QueryBuilder.DesignPane) control.

private void Form1_Load(object sender, EventArgs e)
{
    queryBuilder.SyntaxProvider = mssqlSyntaxProvider1;
    queryBuilder.MetadataLoadingOptions.OfflineMode = true;
    queryBuilder.MetadataContainer.ImportFromXML("Northwind.xml");

    queryBuilder.InitializeDatabaseSchemaTree();

    queryBuilder.DesignPaneControl.DragOver += DesignPaneControl_DragOver;
    queryBuilder.DesignPaneControl.DragDrop += DesignPaneControl_DragDrop;
}

private void DesignPaneControl_DragDrop(object sender, ActiveQueryBuilder.View.CDragEventArgs e)
{
    var data = (DataObject) e.Data;

    var text = data.GetData("Text") as string;

    if(string.IsNullOrEmpty(text)) return;

    var point = new Point(e.X, e.Y);

    if (point != default(Point))
      queryBuilder.AddObjectToActiveUnionSubQueryAtPoint(text, point, "");
    else
      queryBuilder.AddObjectToActiveUnionSubQuery(text, "");
}

private void DesignPaneControl_DragOver(object sender, ActiveQueryBuilder.View.CDragEventArgs e)
{
   var data = (DataObject)e.Data;
   e.Effect = data.GetFormats().Contains("Text") ? CDragDropEffects.Copy: CDragDropEffects.None;
}

private void treeView_ItemDrag(object sender, ItemDragEventArgs e)
{
    if ((e.Item as TreeNode)?.Parent?.Parent != null)
    {
      var node = (TreeNode)e.Item;

      treeView.DoDragDrop(node.Text, DragDropEffects.Copy);
    }
}

Please note that if you want to keep the ability to drop objects from the internal Database Schema Tree control, you must also manually handle dropping of MetadataItem objects to it.

private void queryBuilder1_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}


private void queryBuilder1_DragDrop(object sender, DragEventArgs e)
{
    if (e.Data != null && e.Data.GetDataPresent(typeof(String)))
    {
        String objectName = (String) e.Data.GetData(typeof(String));
        queryBuilder1.ActiveSubQuery.ActiveUnionSubquery.AddObjectWithFKAt(objectName, new Point(e.X, e.Y), "");
    }
}
procedure TfMain.acQueryBuilder1DragDrop(Sender, Source: TObject; 
    X, Y: Integer);
    var selectedNodeName: string;
begin
    Assert((Source = CustomMetadataTree) and (CustomMetadataTree.Selected <> nil));
    selectedNodeName := CustomMetadataTree.Selected.Text;
    acQueryBuilder1.ActiveSubQuery.ActiveUnionSubquery.AddObjectWithFKAt(
        selectedNodeName,
        Point(X, Y)
    );
end;

procedure TfMain.acQueryBuilder1DragOver(Sender, Source: TObject;
    X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
    Accept := (Source = CustomMetadataTree) and (CustomMetadataTree.Selected <> nil);
end;
queryBuilder1.setDropTarget(new DropTarget(this, new DropTargetAdapter()
{
    @Override
    public void dragOver(DropTargetDragEvent event)
    {
        if (!event.getTransferable().isDataFlavorSupported(DataFlavor.stringFlavor))
        {
            event.rejectDrag();
        }
    }

    @Override
    public void drop(DropTargetDropEvent event)
    {
        event.acceptDrop(DnDConstants.ACTION_LINK);

        Transferable transferable = event.getTransferable();

        if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor))
        {
            try
            {
                String objectName = (String) transferable.getTransferData(DataFlavor.stringFlavor);
                queryBuilder1.getActiveSubquery().getActiveUnionSubquery().addObjectWithFKAt(objectName, event.getLocation(), "");
            }
            catch (UnsupportedFlavorException ex)
            {
                // handle exception
            }
            catch (IOException ex)
            {
                // handle exception
            }
        }
    }
}));

Is this article helpful for you?