检查段落属性会丢失选择

时间:2017-02-28 10:34:08

标签: ms-word vsto selection

在我的vsto插件中,我在计时器上有一些简单的代码

private void MainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (!dialogopen & Application.Documents.Count > 0)
        {
            var doc = Application.ActiveDocument;
            Word.InlineShapes shps;
            Word.Paragraphs pars;
            try
            {
                pars = doc.Paragraphs;
            }
            catch (Exception)
            {
                return;
            }
            var pars2 = pars.Cast<Word.Paragraph>().ToList();
            foreach (var obj in pars2)
            {
                if (obj.OutlineLevel == Word.WdOutlineLevel.wdOutlineLevelBodyText )//PROBLEM HERE
                {

                };
            }

        }
    }

一旦到达检查outlinelevel的行,即使我不做某事,activedocument中的选择也会丢失

当然,用户无法使用插件继续取消他的选择...

谷歌没有给我一个东西

感谢

EDIT1

我尝试使用static函数来检查样式,但它没有帮助。这是代码

static public class Helpers
{
    static public Word.Paragraph checkPars(List<Word.Paragraph> pars)
    {
        return pars.FirstOrDefault();//(x) => x.OutlineLevel == Word.WdOutlineLevel.wdOutlineLevelBodyText);
    }
}

正如你所看到的,我不得不删除实际的检查,因为它导致光标闪烁并失去选择

请告知

2 个答案:

答案 0 :(得分:2)

我们使用Application.ScreenUpdating = true;来保留Paragraph中除Range属性之外的所有属性的选择。

然后,我们尝试通过Reflection访问范围,这就是解决方案。

Range rng = (Range)typeof(Paragraph).GetProperty("Range").GetValue(comObj);

答案 1 :(得分:1)

我们试图消除查询ActiveDocument,认为这可能产生导致问题的副作用,但事实并非如此。

然后,我们确认选择没有“丢失”,屏幕更新是唯一的问题,因此我们尝试使用Application.ScreenRefresh恢复用户界面,虽然它确实有效,但每次都会导致屏幕闪烁计时器开火,这还不够好。

最后,知道这只是一个用户界面问题,我尝试了关闭Application.ScreenUpdating ...

ThisAddin

中的

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    Timer timer = new Timer(2000);
    timer.Elapsed += (s, t) =>
    {
        var scrnUpdating = Application.ScreenUpdating;
        Application.ScreenUpdating = false;

        MainTimer.onElapsed(Application, t);

        if (scrnUpdating)
            Application.ScreenUpdating = true;
    };
    timer.Start();
}

在另一个类库中(注意它是静态的,我仍然认为这是最好的方法)...

public static class MainTimer
{
    public static void onElapsed (Word.Application state, System.Timers.ElapsedEventArgs e)
    {
        if (state.Documents.Count > 0)
        {
            var doc = state.ActiveDocument;
            Word.InlineShapes shps;
            Word.Paragraphs pars;
            try
            {
                pars = doc.Paragraphs;
            }
            catch (Exception)
            {
                return;
            }
            var pars2 = pars.Cast<Word.Paragraph>()
                .Where(p => p.OutlineLevel == Word.WdOutlineLevel.wdOutlineLevelBodyText)
                .Select(p => p) // do stuff with the selected parragraphs...
                .ToList();
        }
    }
}

这对我有用。 选择仍然存在,并在UI中显示,没有闪烁。

我还从您的代码中删除了一些过早的枚举:您没有在.ToList()之前使用foreach