如何使用C#VSTO在Excel中处理范围事件的鼠标移动

时间:2014-05-28 13:36:19

标签: c# excel vsto

介绍: 我有一个类,它表示具有类似逻辑的表列:

class ColumnWrapper
{
    int _column;
    int _row;
    string _name;
    string _caption;
    Worksheet _worksheet;

    Dictionary<int, string> _values; // <row offset index, value>

    public void Open()
    {
        // ...
        // Connect to server and get values
        // ...

        Range r = _worksheet.Range[_column, _row];
        r.Value2 = _caption;

        foreach (Range item in _values)
        {
            Range r = _worksheet.Range[_column, _row + item.Key];
            r.Value2 = item.Value;
        }

        var addressStart = String.Concat(ExcelColumnFromNumber(_column), _row);
        var addressEnd = String.Concat(ExcelColumnFromNumber(_column), (_row + _values.Keys.Max()));

        Range range = _worksheet.Range[addressStart, addressEnd];
        _worksheet.Names.Add(_name, )
    }

    public void Delete(string value)
    {
        // Delete row and shift all rows below to up
        int index = _values.First(i => i.Value == value).Key;

        foreach(var key in _values.Where(i => i.Key > index))
            // decrement index

        RefreshValues();
    }
}

excel中的用户可以选择某个范围,然后将其移动到某处。

enter image description here

我需要处理这个事件,因为希望允许用户只移动标题单元格并放弃在所有其他情况下移动。

次要问题:如何以编程方式移动范围?现在,在行删除时,我会通过 _values 集合并递减所有索引,这比删除值的索引更大。之后我重置了所有范围的值,而且速度很慢。但如果只能移动范围,它会更快。

1 个答案:

答案 0 :(得分:0)

没有开箱即用的此类活动。您可以通过使用一些额外的逻辑来模拟许多事件。我认为您可以使用以下逻辑实现所需的事件:

  1. 订阅选择更改活动。
  2. 在事件处理程序中,您应该跟踪上次选择的范围。您将其与当前选定的一个进行比较。如果范围值相同但仅更改位置,则发生移动。然后,您可以使用逻辑来确定是否只移动了标头。如果不是,则将移动恢复到原始位置。
  3. 这应该会让您非常接近您的解决方案,但您可能需要添加一些额外的检查,...或者您可以将此逻辑限制为仅您不希望允许移动的某些范围。

    至于第二个问题,请看Range.Cut method。我记录了移动范围的宏,这是用于移动范围的优秀代码。

    同样setting the values of a whole range比循环遍历单元格和设置单元格值要快得多。