Tworzenie wielopoziomowej listy punktorów za pomocą Word.Interop

Muszę utworzyć wielopoziomową listę punktorów za pośrednictwemMicrosoft.Office.Interop.Word i obecnie zmagam się z jego (okropnym) API (ponownie).

Właśnie stworzyłem następujący przykład (jeszcze nie dynamiczny, tylko dla celów demonstracyjnych) w projekcie VSTO na poziomie dokumentu dla Microsoft Office Word 2010 w języku programowania C #:

Word.Paragraph paragraph = null;
Word.Range range = this.Content;
paragraph = range.Paragraphs.Add();
paragraph.Range.Text = "Item 1";
paragraph.Range.ListFormat.ApplyBulletDefault(Word.WdDefaultListBehavior.wdWord10ListBehavior);
// ATTENTION: We have to outdent the paragraph AFTER its list format has been set, otherwise this has no effect.
// Without this, the the indent of "Item 2" differs from the indent of "Item 1".
paragraph.Outdent();

paragraph.Range.InsertParagraphAfter();

paragraph = range.Paragraphs.Add();
paragraph.Range.Text = "Item 1.1";
// ATTENTION: We have to indent the paragraph AFTER its text has been set, otherwise this has no effect.
paragraph.Indent();
paragraph.Range.InsertParagraphAfter();

paragraph = range.Paragraphs.Add();
paragraph.Range.Text = "Item 1.2";
paragraph.Range.InsertParagraphAfter();

paragraph = range.Paragraphs.Add();
paragraph.Range.Text = "Item 2";
paragraph.Outdent();

Kod robi dokładnie to, czego chcę (po wielu próbach i błędach!), Ale moim zdaniem jest to okropne. Format musi być zastosowany w BARDZO specyficznym punkcie i muszę ręcznie wciąć i odsunąć utworzone akapity.

Więc moje pytanie brzmi:Czy istnieje lepsze podejście do tworzenia wielopoziomowej listy punktorów za pośrednictwemWord.Interop, np. metodami stenograficznymi, których jeszcze nie odkryłem?

Moim celem jest stworzenie wielopoziomowej listy z danych XML (bardziej konkretnie aCustomXMLNode obiekt)

Dwa inne pytania związane z listami wypunktowania istnieją na stosie przepełnienia, ale oba mi nie pomagają (powyższy kod źródłowy jest jedną odpowiedzią na drugie pytanie):

Punkty wypunktowania w słowie z c # Interophttps://stackover.com/questions/3768414/ms-word-list-with-sub-lists

EDYCJA (2013-08-08):

Właśnie zhakowałem coś, co powoduje wyświetlenie dwóch tablic jako listy wypunktowanej z dwoma poziomami (tablica z podelementami jest używana dla każdego elementu głównego, aby był prosty). Wprowadzając rekursję, można utworzyć listę punktorów z nieskończonymi poziomami (teoretycznie). Ale problem pozostaje, kod jest bałagan ...

string[] rootItems = new string[]
{
    "Root Item A", "Root Item B", "Root Item C"
};

string[] subItems = new string[]
{
    "Subitem A", "Subitem B"
};

Word.Paragraph paragraph = null;
Word.Range range = this.Content;
bool appliedListFormat = false;
bool indented = false;

for (int i = 0; i < rootItems.Length; ++i)
{
    paragraph = range.Paragraphs.Add();
    paragraph.Range.Text = rootItems[i];

    if (!appliedListFormat)
    {
        paragraph.Range.ListFormat.ApplyBulletDefault(Word.WdDefaultListBehavior.wdWord10ListBehavior);
        appliedListFormat = true;
    }

    paragraph.Outdent();
    paragraph.Range.InsertParagraphAfter();

    for (int j = 0; j < subItems.Length; ++j)
    {
        paragraph = range.Paragraphs.Add();
        paragraph.Range.Text = subItems[j];

        if (!indented)
        {
            paragraph.Indent();
            indented = true;
        }

        paragraph.Range.InsertParagraphAfter();
    }

    indented = false;
}

// Delete the last paragraph, since otherwise the list ends with an empty sub-item.
paragraph.Range.Delete();

EDYCJA (2013-08-12):

W ostatni piątek myślałem, że osiągnąłem to, co chciałem, ale dziś rano zauważyłem, że moje rozwiązanie działa tylko wtedy, gdy punkt wstawiania znajduje się na końcu dokumentu. Stworzyłem następujący prosty przykład, aby zademonstrować (błędne) zachowanie. Podsumowując mój problem: jestem w stanie tworzyć wielopoziomowe listy punktorów na końcu dokumentutylko. Jak tylko zmienię bieżący wybór (np. Na początek dokumentu), lista zostanie zniszczona. O ile widzę, jest to związane z (automatycznym lub nieautomatycznym) rozszerzeniemRange przedmioty. Do tej pory wiele próbowałem (prawie go tracę), ale dla mnie to wszystko jest kultem cargo. Jedyne, co chcę zrobić, to wstawić jeden element za drugim (czy niemożliwe jest utworzenie kontrolki treściwewnątrz akapit, tak aby po tekście akapitu następowała kontrola treści?)i do tego w każdymRange aDocument. Stworzę Gist na GitHub z moją aktualnąCustomXMLPart zajęcia wieczorowe tego wieczoru. W końcu ktoś może mi pomóc rozwiązać ten uciążliwy problem.

private void buttonTestStatic_Click(object sender, RibbonControlEventArgs e)
{
    Word.Range range = Globals.ThisDocument.Application.Selection.Range;
    Word.ListGallery listGallery = Globals.ThisDocument.Application.ListGalleries[Word.WdListGalleryType.wdBulletGallery];
    Word.Paragraph paragraph = null;
    Word.ListFormat listFormat = null;

    // TODO At the end of the document, the ranges are automatically expanded and inbetween not?

    paragraph = range.Paragraphs.Add();
    listFormat = paragraph.Range.ListFormat;
    paragraph.Range.Text = "Root Item A";
    this.ApplyListTemplate(listGallery, listFormat, 1);
    paragraph.Range.InsertParagraphAfter();

    paragraph = paragraph.Range.Paragraphs.Add();
    listFormat = paragraph.Range.ListFormat;
    paragraph.Range.Text = "Child Item A.1";
    this.ApplyListTemplate(listGallery, listFormat, 2);
    paragraph.Range.InsertParagraphAfter();

    paragraph = paragraph.Range.Paragraphs.Add();
    listFormat = paragraph.Range.ListFormat;
    paragraph.Range.Text = "Child Item A.2";
    this.ApplyListTemplate(listGallery, listFormat, 2);
    paragraph.Range.InsertParagraphAfter();

    paragraph = paragraph.Range.Paragraphs.Add();
    listFormat = paragraph.Range.ListFormat;
    paragraph.Range.Text = "Root Item B";
    this.ApplyListTemplate(listGallery, listFormat, 1);
    paragraph.Range.InsertParagraphAfter();
}

private void ApplyListTemplate(Word.ListGallery listGallery, Word.ListFormat listFormat, int level = 1)
{
    listFormat.ApplyListTemplateWithLevel(
        listGallery.ListTemplates[level],
        ContinuePreviousList: true,
        ApplyTo: Word.WdListApplyTo.wdListApplyToSelection,
        DefaultListBehavior: Word.WdDefaultListBehavior.wdWord10ListBehavior,
        ApplyLevel: level);
}

EDYCJA (2013-08-12): Skonfigurowałem repozytorium GitHubtutaj co pokazuje mój problem zWord.Range przedmioty. TheOnClickButton metoda w plikuRibbon.cs wywołuje moją niestandardową klasę mapowania. Komentarze tam opisują problem. jawiedzieć że moje problemy są związane z argumentemWord.Range odwołanie do obiektu, ale wszystkie inne rozwiązania, które próbowałem (np. modyfikowanie zasięgu wewnątrz klasy), zawiodły jeszcze trudniej. Najlepszym rozwiązaniem, jakie do tej pory osiągnąłem, jest określenieDocument.Content zakres jako argument dlaMapToCustomControlsIn metoda. To wstawia ładnie sformatowaną wielopoziomową listę punktorów (z niestandardowymi częściami XML związanymi z kontrolkami treści) dokoniec dokumentu. Chcę wstawić tę listęw pozycji niestandardowej do dokumentu (np. bieżący wybór przezWord.Selection.Range).

questionAnswers(1)

yourAnswerToTheQuestion