拖放到网格后如何在应用程序中重新获得焦点
How to regain focus in application after drag and drop to grid
在我的应用程序中,我有一个包含两个面板的表单。在一个面板内是一个按钮。另一个内部是 DevExpress Grid 控件。网格由 3 列组成。您可以将值从一列拖到另一列以进行复制。
我的问题是,每当我从一栏到另一栏执行 drag-and-drop 时,对应用程序的关注就会进入异常状态。网格保持聚焦;我可以将鼠标悬停在 headers 上并看到它们的反应正常。然而,应用程序的其余部分没有重点。将鼠标悬停在其他面板中的按钮上没有反应,菜单或表单控件也没有反应。如果我单击该按钮,它的反应就像我单击了一个未聚焦的应用程序一样。我必须再次单击才能真正激活按钮。除网格外,每个控件都相同。
我试过在按钮和表单上使用 Activate() 和 Focus() 但无济于事。
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)
{
}
}
}
确保在 GridView 的 Mouse~ 事件处理程序中将 DXMouseEventArgs.Handled 属性 设置为 true。它保证禁止默认处理这些事件。查看此 example 以了解如何执行此操作。
我想出了我自己的问题。从 MouseDown 事件中调用 DoDragDrop() 似乎无法正常工作。正确的方法是从 MouseMove() 调用它。 documentation on MSDN 在其示例代码中暗示了这一点。
在我的应用程序中,我有一个包含两个面板的表单。在一个面板内是一个按钮。另一个内部是 DevExpress Grid 控件。网格由 3 列组成。您可以将值从一列拖到另一列以进行复制。
我的问题是,每当我从一栏到另一栏执行 drag-and-drop 时,对应用程序的关注就会进入异常状态。网格保持聚焦;我可以将鼠标悬停在 headers 上并看到它们的反应正常。然而,应用程序的其余部分没有重点。将鼠标悬停在其他面板中的按钮上没有反应,菜单或表单控件也没有反应。如果我单击该按钮,它的反应就像我单击了一个未聚焦的应用程序一样。我必须再次单击才能真正激活按钮。除网格外,每个控件都相同。
我试过在按钮和表单上使用 Activate() 和 Focus() 但无济于事。
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)
{
}
}
}
确保在 GridView 的 Mouse~ 事件处理程序中将 DXMouseEventArgs.Handled 属性 设置为 true。它保证禁止默认处理这些事件。查看此 example 以了解如何执行此操作。
我想出了我自己的问题。从 MouseDown 事件中调用 DoDragDrop() 似乎无法正常工作。正确的方法是从 MouseMove() 调用它。 documentation on MSDN 在其示例代码中暗示了这一点。