Kurt Stutsman
Kurt Stutsman

Reputation: 4034

How to regain focus in application after drag and drop to grid

In my application, I have a form with two panels. Inside one panel is a button. Inside the other is a DevExpress Grid control. The grid is made up of 3 columns. You can drag values from one column into the other to copy it.

My problem is that whenever I do a drag-and-drop from one column to another, the focus on the application goes into an unusual state. The grid remains focused; I can mouse over the headers and see them react as normal. However the rest of the application is not focused. Mouse over the button in the other panel does not react, nor do the menus or form controls. If I click on the button, it reacts like I clicked on an unfocused application. I have to click again to actually activate the button. Same for every control except the grid.

I have tried using Activate() and Focus() on the button and form but to no avail.

namespace Company.StuffUploader
{
    public partial class ComputationGrid : DevExpress.XtraEditors.XtraUserControl
    {
        private BindingList<ComputationLinkModel> _links = new BindingList<ComputationLinkModel>();

        public List<ComputationLinkModel> ComputationLinkModels
        {
            get
            {
                return new List<ComputationLinkModel>(_links);
            }
        }

        public ComputationGrid()
        {
            InitializeComponent();
        }

        private void ComputationGrid_Load(object sender, EventArgs e)
        {
            _gridControl.DataSource = _links;
        }

        private DragDropEffects GetDragEffect(DragEventArgs e)
        {
            var text = e.Data.GetData("System.String") as string;
            if (text == null)
                return DragDropEffects.None;

            var link = GetLinkFromScreenPoint(new Point(e.X, e.Y));
            if (link == null)
                return DragDropEffects.None;

            var tokens = text.Split('\t');
            if (tokens.Count() != 2)
                return DragDropEffects.None;

            var dateString = link.movedate.ToString("yyyy-MM-dd");
            if (link.StuffSurfaceName == tokens[0] && dateString != tokens[1])
                return DragDropEffects.Move;
            else
                return DragDropEffects.None;
        }

        private ComputationLinkModel GetLinkFromScreenPoint(Point screenPt)
        {
            var pt = _gridControl.PointToClient(screenPt);
            var hitInfo = _gridView.CalcHitInfo(pt);
            return _gridView.GetRow(hitInfo.RowHandle) as ComputationLinkModel;
        }

        private void _gridControl_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {

                var hitInfo = _gridView.CalcHitInfo(e.Location);
                if (hitInfo == null || !hitInfo.InRowCell)
                    return;

                // Only allow dragging from target column
                if (hitInfo.Column.AbsoluteIndex != 0)
                    return;

                var link = _gridView.GetRow(hitInfo.RowHandle) as ComputationLinkModel;
                if (link == null)
                    return;

                var item = string.Format("{0}\t{1}", link.StuffSurfaceName, link.movedate.ToString("yyyy-MM-dd"));
                DoDragDrop(item, DragDropEffects.Move);
            }
        }

        private void _gridControl_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = GetDragEffect(e);
        }

        private void _gridControl_DragDrop(object sender, DragEventArgs e)
        {
        }

        private void _gridControl_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = GetDragEffect(e);
        }

        private void _unlinkButton_Click(object sender, EventArgs e)
        {
        }
    }
}

Upvotes: 1

Views: 1016

Answers (2)

Kurt Stutsman
Kurt Stutsman

Reputation: 4034

I figured out my own problem. Calling DoDragDrop() from within MouseDown event does not seem to work correctly. The proper way is to call it from MouseMove(). The documentation on MSDN hints at this in its example code.

Upvotes: 1

Svetlana
Svetlana

Reputation: 421

Ensure that you set the DXMouseEventArgs.Handled property to true in the GridView's Mouse~ event handlers. It guarantees that default handling of these events will be prohibited. Review this example to see how to do this.

Upvotes: 0

Related Questions