7

私のwinformsスキルは少し錆びています。を使用しBindingSourceていDataGridViewます。KeyDownで、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()は正しく呼び出されますが、何も起こらないことに注意してください。

編集DataGridView:興味深いことに、これを'sの代わりにボタン(前/次)からトリガーすると、期待どおりに機能しますOnKeyDown、何かアイデアはありますか?

4

2 に答える 2

2

グリッドは、上下に移動すると、下にあるバインディングソースの位置を自動的に移動します。

選択を上からボタンへ、またはその逆にしたい場合は、grid_KeyDownイベントを処理してその位置を確認できます。残念ながら、ポッションを動かそうとすると、グリッドビューの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;
        }
    }

これは私がそれを得ることができたのと同じくらいきれいでした。

于 2013-03-11T19:13:55.020 に答える
2

Jens Klosterのおかげで、この回避策を見つけました。彼が述べたように、DataGridViewすでにそれの位置の移動をサポートしていますBindingSource。したがって、フォーカスがあり、上/下矢印を押すと、BindingSource's MoveNext/MovePreviousが暗黙的に呼び出されます。

KeyUp代わりに、イベント(後でイベント)を処理したときに、選択したアイテムが2つの位置に「ジャンプ」したことに気付きましたKeyDown。1つはプログラム用で、もう1つは組み込みの移動用です。

したがって、上/下キーが押された場合に、位置を最初から最後に、またはその逆に移動する方法を見つける必要があるだけです。したがって、BindingSource.PositionChanged後で確認できるbool変数を設定するためにイベントを処理しました。

bool positionChanged = false;
private void Source_PositionChanged(object sender, EventArgs e)
{
    positionChanged = true;
}

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

    positionChanged = false;
}

private void previousItem()
{
    BindingSource bs = null;
    switch (this.Type)
    {
        case AdminType.Channel:
            bs = channelBindingSource;
            break;
        default:
            break;
    }
    if (!positionChanged && bs.Position == 0)
        bs.MoveLast();
    else if (!positionChanged)
        bs.MovePrevious();
}

private void nextItem()
{
    BindingSource bs = null;
    switch (this.Type)
    {
        case AdminType.Channel:
            bs = channelBindingSource;
            break;
        default:
            break;
    }
    if (!positionChanged && bs.Position == bs.Count - 1)
        bs.MoveFirst();
    else if (!positionChanged)
        bs.MoveNext();
}

これは少し不器用でエラーが発生しやすいので、私はまだより良い解決策を開いています。

于 2013-03-11T14:58:32.093 に答える