BindingSource MoveFirst/MoveLast不起作用

Tim*_*ter 6 c# data-binding bindingsource winforms

我的winforms技能有点生疏.我正在使用BindingSource一个DataGridView.对KeyDownDataGridView,我想选择无论你希望工作的一个/上一个纪录.

如果用户Keys.Down在选择最后一个项目时点击,我想选择第一个,如果在选择第一个项目时点击,则选择最后Keys.Up一个.但是没有任何事情发生

这是代码:

private void  Grid_Keydown(Object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Up)
        previousItem();
    else if (e.KeyCode == Keys.Down)
        nextItem();
}

private void previousItem()
{
    BindingSource bs = null;
    switch (this.Type) // a custom enum
    {
        case AdminType.Channel:  
            bs = channelBindingSource;
            break;
        default:
            break;
    }
    if (bs.Position - 1 < 0)
        bs.MoveLast();
    else
        bs.MovePrevious();
}

private void nextItem()
{
    BindingSource bs = null;
    switch (this.Type)
    {
        case AdminType.Channel:
            bs = channelBindingSource;
            break;
        default:
            break;
    }
    if (bs.Position + 1 >= bs.Count)
        bs.MoveFirst();
    else
        bs.MoveNext();
}
Run Code Online (Sandbox Code Playgroud)

请注意bs.MoveFirst()/ bs.MoveLast()正确调用,但没有任何反应.

编辑:有趣的是,当我从一个按钮(上一个/下一个)而不是DataGridView's OnKeyDown,任何想法触发它时,它按预期工作?

Jen*_*ter 2

当您上下移动时,网格会自动移动底层绑定源的位置。

如果您希望选择从顶部到按钮,反之亦然 - 您可以处理该grid_KeyDown事件并检查其位置。不幸的是,如果您尝试移动位置,它会被 gridview 的Row_Enter事件覆盖。从而改变绑定源的位置。

如果Grid_Keyup位置已经设​​置,那么您不知道用户是否只是移动到该行,或者他/她是否想要离开该行。在这里设置bindingSource.Position实际上是有效的 - 并且不会被网格覆盖。

您也可以使用DataGridViewRow.Selected = true但他不会移动底层绑定源的位置。对于启用多选的网格来说,这也不是理想的选择。

丑陋的事实是,您必须使用布尔值(就像您在自己的答案中所做的那样)来控制行是否应该跳转。:(

但是你不需要从PositionChanged事件中控制它,你可以通过处理grid_Keydown事件来做到这一点:

 private bool _changePost;
    private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
    {
        var view = sender as DataGridView;
        var bs = bindingSource1;

        if (e.KeyData == Keys.Up)
        {
            if (bs.Position == 0 && _changePost)
            {
                _changePost = false;
                bs.MoveLast();
            }
            if (bs.Position == 0 && !_changePost)
                _changePost = true;

        }
        else if (e.KeyData == Keys.Down)
        {
            if (bs.Position == bs.Count - 1 && _changePost)
            {
                bs.MoveFirst();
                _changePost = false;
            }
            if (bs.Position == bs.Count - 1 && !_changePost)
                _changePost = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是我能得到的最干净的了。