检查段落 属性 丢失选择
checking paragraph property loses the 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
{
};
}
}
}
一旦到达检查大纲级别的行,即使我什么都不做,活动文档中的选择也会丢失
当然,用户不能使用不断取消选择的插件...
谷歌搜索什么也没给我
谢谢
EDIT1
我尝试制作一个 static
函数来检查样式,但它没有帮助。这是代码
static public class Helpers
{
static public Word.Paragraph checkPars(List<Word.Paragraph> pars)
{
return pars.FirstOrDefault();//(x) => x.OutlineLevel == Word.WdOutlineLevel.wdOutlineLevelBodyText);
}
}
如您所见,我不得不删除实际的检查,因为它导致光标闪烁并失去选择
请指教
我们试图消除查询,ActiveDocument
认为查询可能会产生导致问题的副作用,但事实并非如此。
然后,我们确认选择不是 "lost",屏幕更新是唯一的问题,所以我们尝试用 Application.ScreenRefresh
恢复 UI,虽然它确实有效,它会导致每次计时器触发时屏幕闪烁,这还不够好。
最后,知道这只是一个 UI 问题,我尝试简单地关闭 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();
}
在另一个class库中(注意它是静态的,我仍然认为这是最好的方法)...
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显示,不闪烁。
我还从您的代码中删除了一些过早的枚举:您没有在 foreach
之前添加 .ToList()
。
我们使用 Application.ScreenUpdating = true;
,这会保留 Paragraph
中所有属性的选择,Range
属性.
除外
然后,我们尝试通过反射访问范围,这就是解决方案。
Range rng = (Range)typeof(Paragraph).GetProperty("Range").GetValue(comObj);
在我的 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
{
};
}
}
}
一旦到达检查大纲级别的行,即使我什么都不做,活动文档中的选择也会丢失
当然,用户不能使用不断取消选择的插件...
谷歌搜索什么也没给我
谢谢
EDIT1
我尝试制作一个 static
函数来检查样式,但它没有帮助。这是代码
static public class Helpers
{
static public Word.Paragraph checkPars(List<Word.Paragraph> pars)
{
return pars.FirstOrDefault();//(x) => x.OutlineLevel == Word.WdOutlineLevel.wdOutlineLevelBodyText);
}
}
如您所见,我不得不删除实际的检查,因为它导致光标闪烁并失去选择
请指教
我们试图消除查询,ActiveDocument
认为查询可能会产生导致问题的副作用,但事实并非如此。
然后,我们确认选择不是 "lost",屏幕更新是唯一的问题,所以我们尝试用 Application.ScreenRefresh
恢复 UI,虽然它确实有效,它会导致每次计时器触发时屏幕闪烁,这还不够好。
最后,知道这只是一个 UI 问题,我尝试简单地关闭 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();
}
在另一个class库中(注意它是静态的,我仍然认为这是最好的方法)...
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显示,不闪烁。
我还从您的代码中删除了一些过早的枚举:您没有在 foreach
之前添加 .ToList()
。
我们使用 Application.ScreenUpdating = true;
,这会保留 Paragraph
中所有属性的选择,Range
属性.
然后,我们尝试通过反射访问范围,这就是解决方案。
Range rng = (Range)typeof(Paragraph).GetProperty("Range").GetValue(comObj);