简体   繁体   English

使用C#DataGridView自定义选择

[英]Custom selection with C# DataGridView

I have a DataGridView with single text characters in it.. basically like Character Map, but want to be able to select groups of the cells left-to-right, as if it were text. 我有一个带有单个文本字符的DataGridView。基本上像字符映射一样,但是希望能够从左到右选择单元格的组,就好像它是文本一样。

Ie the default behaviour if I select 2 cells vertically is for only those 2 cells to be selected. 即,如果我垂直选择2个单元格,则默认行为是仅选择这2个单元格。 However, I want it to select all cells to the right of the top row, and to the left of the second row. 但是,我希望它选择第一行右侧和第二行左侧的所有单元格。 Just like if you were to highlight two vertical characters in this question text. 就像您要在此问题文本中突出显示两个垂直字符一样。

Is it possible? 可能吗? (And have I managed to explain it in a way that makes sense?!) (而且我是否设法以一种有意义的方式对其进行了解释?!)

Thanks! 谢谢!

EDIT: Added a couple of images to help explain this better. 编辑:添加了几个图像,以帮助更好地解释这一点。

Firstly, if I select 'P' and drag down to 'd', this is what gets selected: 首先,如果我选择“ P”并向下拖动到“ d”,则将选择以下内容: 默认的DataGridView行为

What I would like to happen in this case, is this: 在这种情况下,我想发生的是: 在此处输入图片说明

Hopefully this makes it more clear, thanks :) 希望这可以使它更清楚,谢谢:)

This works, take a look 这个可行,看看

private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.DataSource = li;
        dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
        dataGridView1.SelectionChanged += dataGridView1_SelectionChanged;
    }

    private void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        var la = dataGridView1.SelectedCells;
        if (la.Count == 2)
        {
            var rowFirst = ((DataGridViewCell)la[0]).RowIndex;
            var columnFirst = ((DataGridViewCell)la[0]).ColumnIndex;

            var rowSecond = ((DataGridViewCell)la[1]).RowIndex;
            var columnSecond = ((DataGridViewCell)la[1]).ColumnIndex;

            for (int column = 0; column <= columnFirst; column++)
            {
                dataGridView1[column, rowFirst].Selected = true;
            }

            for (int column = columnSecond; column < dataGridView1.ColumnCount; column++)
            {
                dataGridView1[column, rowSecond].Selected = true;
            }
        }
    }

Expanding on simple-thomas's answer with a more generic solution, I came up with this. 通过使用更通用的解决方案扩展简单托马斯的答案,我想到了这一点。 It doesn't handle a shrinking selection very well, but it's good enough for my purposes. 它不能很好地处理缩小的选择,但对于我的目的来说已经足够了。 Thanks simple-thomas! 谢谢简单托马斯!

    private void characterGrid_SelectionChanged( object sender, EventArgs e )
    {
        if ( SelectionChanging == true )
        {
            return;
        }

        SelectionChanging = true;

        var la = characterGrid.SelectedCells;
        if ( la.Count > 1 )
        {
            var sorted = new List<DataGridViewCell>();
            System.Collections.IEnumerator enumerator = la.GetEnumerator();
            while ( enumerator.MoveNext() )
            {
                sorted.Add( (DataGridViewCell)enumerator.Current );
            }
            sorted.Sort( delegate( DataGridViewCell t1, DataGridViewCell t2 )
            {
                if ( t1.RowIndex != t2.RowIndex )
                {
                    return t1.RowIndex.CompareTo( t2.RowIndex );
                }
                else
                {
                    return t1.ColumnIndex.CompareTo( t2.ColumnIndex );
                }
            });

            var rowFirst = ( (DataGridViewCell)sorted[ 0 ] ).RowIndex;
            var columnFirst = ( (DataGridViewCell)sorted[ 0 ] ).ColumnIndex;

            var rowLast = ( (DataGridViewCell)sorted[ sorted.Count - 1 ] ).RowIndex;
            var columnLast = ( (DataGridViewCell)sorted[ sorted.Count - 1 ] ).ColumnIndex;

            if ( rowLast > rowFirst )
            {
                // select first row
                for ( int column = columnFirst; column < characterGrid.ColumnCount; column++ )
                {
                    characterGrid[ column, rowFirst ].Selected = true;
                }

                // in between
                for ( int row = rowFirst + 1; row < rowLast; row++ )
                {
                    for ( int column = 0; column < characterGrid.ColumnCount; column++ )
                    {
                        characterGrid[ column, row ].Selected = true;
                    }
                }

                // last row
                for ( int column = 0; column <= columnLast; column++ )
                {
                    characterGrid[ column, rowLast ].Selected = true;
                }
            }
        }

        SelectionChanging = false;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM