BindingSource MoveFirst / MoveLast不起作用

时间:2013-03-11 12:42:16

标签: c# winforms data-binding bindingsource

我的winforms技能有点生疏。我使用BindingSource表示DataGridView。在KeyDown的{​​{1}}上,我想选择符合要求的下一个/上一个记录。

如果用户在选择最后一个项目时点击DataGridView,我想选择第一个,如果在选择第一个项目时点击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(); } / bs.MoveFirst()被正确调用但没有任何反应。

修改:有趣的是,当我从按钮(上一个/下一个)而不是bs.MoveLast()的{​​{1}}触发此任何想法时,它会按预期工作吗?< / p>

2 个答案:

答案 0 :(得分:2)

感谢Jens Kloster,我找到了这个解决方法。正如他所提到的,DataGridView已经支持移动它的位置BindingSource。因此,如果它具有焦点并且您向上/向下箭头,那么BindingSource的{​​{1}} / MoveNext会被隐含地调用。

我注意到,当我处理MovePrevious事件(稍后是KeyUp事件)时,所选项目“跳转”了两个位置,一个用于程序设计,一个用于内置移动。

所以我只需要找到一种方法将位置从第一个移动到最后一个,反之亦然,如果按下向上/向下键。因此我处理了KeyDown事件以设置bool变量,我可以稍后检查:

BindingSource.PositionChanged

我仍然愿意接受更好的解决方案,因为这有点笨拙且容易出错。

答案 1 :(得分:2)

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

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

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;
        }
    }

这就像我能得到的一样干净。