Auto Break between Checkbox and Text in C#

2020-04-30 02:33发布

问题:

I hope you can help me with my problem.

I want to automatically generate a Word checklist with a C# program.

But I can't get it to put the text behind the checkbox. The text always lands in a new line under the checkbox.

How can I solve this problem?

You know some other functions?

    public void createChecklist()
    {
        Application app = new Application();
        app.Visible = true;
        Document doc = app.Documents.Add();
        Paragraph para = doc.Paragraphs.Add();

        ContentControl checkbox = para.Range.ContentControls.Add(WdContentControlType.wdContentControlCheckBox);
        para.Range.InsertAfter("sdjsakd");

        doc.SaveAs2("C:\\tmp\\checklist.docx");
        app.Quit();

    }

回答1:

The reason for the behavior is because the "target" for the text is the range of the entire paragraph. So when something is inserted after, it's inserted after the paragraph.

The key to this is to bring the range back to within the paragraph - to not include the paragraph mark. (The paragraph mark is not visible in the screen shot because the display of non-printing characters is suppressed. Click the "backwards P" in the Home tab of the Ribbon and the paragraph mark should be visible.)

There are various ways to approach this; Range.MoveEndis used quite often (below).

Note: It's dangerous when using COM "interop" to not clean up the objects. This could quickly lead to "orphaned" instances of the application staying in memory. I've added that to the code sample since the code in the question quits the Word application.

public void createChecklist()
{
    Application app = new Application();
    app.Visible = true;
    Document doc = app.Documents.Add();
    Paragraph para = doc.Paragraphs.Add();
    Range rng = para.Range;

    ContentControl checkbox = rng.ContentControls.Add(WdContentControlType.wdContentControlCheckBox);
    rng.MoveEnd(WdUnits.wdCharacter, -1);
    rng.InsertAfter(" sdjsakd");

    doc.SaveAs2("C:\\tmp\\checklist.docx");
  //Release the COM objects and clean up
    checkbox = null;
    rng = null;
    para = null;
    doc = null;
    app.Quit();
    app = null;
    GC.Collect(); GC.AwaitPendingFinalizers();
    GC.Collect(); GC.AwaitPendingFinalizers();

}

Added note to clarify question of why run the garbage collection twice:

This information comes from Andrew Whitechapel's ".Net Development for Microsoft Office", Chapter 2, the extract of which is no longer available on MSDN, so quoted here:

Note that we're repeating the calls to Collect and WaitForPendingFinalizersThis is because the memory for the [Office application reference] might have survived the first pass, although it will then have been marked for collection on the next pass. So we will make a second pass to clean up anything that survived the first pass but was otherwise available for collection.