Creación de una lista de viñetas de varios niveles con Word.Interop

Necesito crear una lista de viñetas de varios niveles a través deMicrosoft.Office.Interop.Word y actualmente estoy luchando con su (horrible) API (otra vez).

Acabo de crear el siguiente ejemplo (aún no dinámico, solo para fines de demostración) en un proyecto de nivel de documento VSTO para Microsoft Office Word 2010 en el lenguaje de programación 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();

El código hace exactamente lo que quiero (después de mucho intento y error), pero en mi opinión es horrible. El formato debe aplicarse en un punto MUY específico y tengo que sangrar manualmente y superar los párrafos creados.

Así que mi pregunta es:¿Existe un mejor enfoque para crear una lista de viñetas de varios niveles a través deWord.Interop, p.ej. A través de métodos abreviados que no he descubierto todavía?

Mi objetivo es crear una lista de múltiples niveles a partir de datos XML (más específica unaCustomXMLNode objeto)

Existen otras dos preguntas relacionadas con las listas de viñetas en Stack Overflow, pero ambas no me ayudan (el código fuente anterior es una respuesta a la segunda pregunta):

Puntos de bala en Word con c # Interoperabilidadhttps://stackoverflow.com/questions/3768414/ms-word-list-with-sub-lists

EDITAR (2013-08-08):

Acabo de piratear algo que genera dos matrices como una lista con dos niveles (la matriz con los subelementos se usa para cada elemento raíz, para que sea simple). Al introducir la recursión, uno podría crear una lista de viñetas con niveles infinitos (teóricamente). Pero el problema sigue, el código es un desastre ...

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();

EDITAR (2013-08-12):

El viernes pasado pensé que había logrado lo que quería, pero esta mañana me di cuenta de que mi solución solo funciona si el punto de inserción se encuentra al final del documento. He creado el siguiente ejemplo simple para demostrar el comportamiento (erróneo). Para concluir mi problema: puedo crear listas de viñetas de varios niveles al final del documentosolamente. Tan pronto como cambio la selección actual (por ejemplo, al inicio del documento), la lista se destruye. Por lo que puedo ver, esto está relacionado con la extensión (automática o no automática) de laRange objetos. He intentado mucho hasta ahora (casi lo estoy perdiendo), pero para mí todo es un culto a la carga. Lo único que quiero hacer es insertar un elemento después de otro (es imposible crear un control de contenido)dentro un párrafo, de modo que el texto del párrafo sea seguido por el control de contenido?)y a que en cualquierRange de unDocument. Crearé un Gist en GitHub con mi actualCustomXMLPart clase obligatoria esta noche. Finalmente, alguien puede ayudarme a solucionar ese problema molesto.

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);
}

EDITAR (2013-08-12): He configurado un repositorio de GitHubaquí lo que demuestra mi problema con elWord.Range objetos. losOnClickButton método en el archivoRibbon.cs invoca mi clase de asignador personalizado. Los comentarios allí describen el problema. yosaber que mis problemas están relacionados con el argumentoWord.Range referencia del objeto, pero todas las demás soluciones que probé (por ejemplo, modificar el rango dentro de la clase) fallaron aún más. La mejor solución que he logrado hasta ahora, es especificar elDocument.Content rango como el argumento para elMapToCustomControlsIn método. Esto inserta una lista de viñetas de múltiples niveles bien formateada (con partes XML personalizadas vinculadas a los controles de contenido) a lafin del documento. Lo que quiero es insertar esa listaen una posición personalizada en el documento (por ejemplo, la selección actual a través deWord.Selection.Range).

Respuestas a la pregunta(1)

Su respuesta a la pregunta