Как работать со списками в .NET
Как работать со списками в .NET
Нумерованные и маркированные списки в документе Word строятся из трёх взаимодействующих объектов: List, переиспользуемого определения нумерации; ListFormat, который указывает конкретному абзацу, к какому списку и уровню он принадлежит; и ListLevel, содержащего фактическое форматирование для одного уровня. Это руководство показывает, как применить список к абзацу, не позволять отдельным спискам использовать один счётчик, перемещать абзацы между уровнями и настраивать форматирование нумерации и маркеров с помощью Aspose.Words FOSS для .NET.
Пошаговое руководство
Шаг 1: Применить список к абзацу
Используйте ListFormat.ApplyBulletDefault() или ApplyNumberDefault() в форматировании абзаца, чтобы применить стандартный маркерный или нумерованный список Word за один вызов — это самый быстрый способ применить стандартный список. Для конкретного предопределённого формата вместо значения по умолчанию вызовите Document.Lists (это ListCollection) .Add(listTemplate) с параметром ListTemplate, например BulletDisk, BulletSquare, NumberArabicDot или NumberUppercaseRomanDot, чтобы создать List из одного из встроенных форматов Word, или AddSingleLevelList(listTemplate) для одноуровневого варианта. Как только у абзаца есть форматирование списка, ListFormat.IsListItem сообщает true, а ListFormat.List/ListLevelNumber определяют, какой список и уровень он использует.
Шаг 2: Предоставить новой группе абзацев независимую нумерацию
Параграфы, чей ListFormat.List указывает на один и тот же общий объект List, продолжают один и тот же счётчик. Когда новой группе параграфов требуется нумерация, начинающаяся с 1 независимо, вызовите ListCollection.AddCopy(srcList) для дублирования существующего определения списка, затем примените копию к новым параграфам вместо повторного использования оригинала. ListCollection.GetListByListId(listId) извлекает конкретный список по его ListId, когда вам нужно найти его, а не создавать, и Count сообщает, сколько списков в документе в данный момент.
Шаг 3: Переместить параграф между уровнями списка
Используйте ListFormat.ListIndent(), чтобы переместить параграф на один уровень глубже в его список, и ListOutdent(), чтобы переместить его на один уровень выше — те же операции, которые Word выполняет при нажатии Tab и Shift+Tab в начале абзаца списка. Предпочтите эти методы вместо прямой установки ListLevelNumber, поскольку они сохраняют внутреннюю согласованность форматирования списка в абзаце. Вызовите RemoveNumbers(), чтобы полностью удалить форматирование списка из абзаца.
Шаг 4: Настроить формат нумерации уровня списка
Получите конкретный уровень через List.ListLevels (это ListLevelCollection), затем задайте ListLevel.NumberStyle (значение NumberStyle, например Arabic, UppercaseRoman, LowercaseLetter или Bullet) и NumberFormat — строку формата, объединяющую номер с литеральным текстом, таким как точка или скобка — совместно, поскольку несоответствующая пара приводит к неожиданному отображению. StartAt задаёт начальное число уровня, а RestartAfterLevel управляет тем, чьё увеличение более высокого уровня перезапускает счётчик этого уровня — задавайте его явно для вложенных списков, а не полагайтесь на поведение перезапуска по умолчанию. Alignment (Left, Center, Right) и TrailingCharacter (Tab, Space, Nothing) контролируют позицию метки и разделитель между меткой и текстом абзаца, вместе с TabPosition, NumberPosition и TextPosition для точной раскладки. IsLegal принуждает нумерацию в юридическом стиле (всегда арабские цифры) независимо от NumberStyle.
Шаг 5: Добавить картинку-маркер к уровню списка
Вызовите ListLevel.CreatePictureBullet() на целевом уровне, чтобы создать определение картинного маркера, затем укажите ImageData маркера, прежде чем удалять существующее текстовое форматирование маркера на том же уровне. Вызовите DeletePictureBullet(), чтобы удалить картинный маркер и вернуть текстовое форматирование маркера.
Шаг 6: Проверить отрисованную метку элемента списка
ListLabel описывает метку, фактически отображаемую для одного экземпляра пункта списка, получаемую из форматирования абзаца элемента. LabelString — это буквальный текст, который Word отображает — например «3.» или «•» — LabelValue представляет собой базовое числовое значение, а Font — собственное форматирование метки, независимое от форматирования текста абзаца. Чтобы вычислить значение метки в произвольной позиции последовательности без рендеринга всего списка, вызовите ListLevel.GetEffectiveValue(index, numberStyle, customNumberStyleFormat).
Распространённые проблемы и их решения
Два абзаца, которые должны нумероваться независимо, продолжают одну и ту же последовательность. Оба абзаца’ ListFormat.List относится к тому же общему List объект. Дайте второй группе собственный список через ListCollection.AddCopy(srcList) вместо повторного использования того же List.
Пользовательская строка формата нумерации не отображается как ожидается. ListLevel.NumberFormat не соответствует ожидаемому шаблону уровня NumberStyle. Проверьте NumberFormat and NumberStyle установлены последовательно для редактируемого уровня.
Отступы списка выглядят неправильно после программного изменения уровней. ListLevelNumber было установлено напрямую без обновления связанных свойств позиции. Используйте ListFormat.ListIndent()/ListOutdent() вместо установки ListLevelNumber напрямую.
Картинка-маркер не отображается на уровне. Для этого уровня не был создан картинный маркер, либо всё ещё активное форматирование текстового маркера по умолчанию. Вызовите ListLevel.CreatePictureBullet() и передайте данные изображения перед удалением форматирования текстового маркера.
Список, связанный со стилем, не реагирует на прямые изменения форматирования. Check List.IsListStyleReference — форматирование списка, ссылающегося на стиль, контролируется его связанным Style (через List.Style), а не путем редактирования списка напрямую. Сравните с IsListStyleDefinition чтобы отличить список, определяющий собственное форматирование.
Часто задаваемые вопросы
В чем разница между List и ListFormat?
List — это переиспользуемое определение нумерации или маркера, общее для нескольких абзацев. ListFormat относится к каждому абзацу — оно указывает, какой List использует конкретный абзац и на каком уровне, через ListFormat.List и ListLevelNumber.
Как проверить, является ли абзац уже частью списка?
Прочитайте ListFormat.IsListItem о форматировании абзаца. Если true, ListFormat.List и ListLevelNumber определяют, к какому списку и уровню он относится.
Как заставить новый список начинать нумерацию с 1 независимо от существующего списка?
Используйте ListCollection.AddCopy(srcList) для создания независимой копии определения списка, затем примените копию к новым абзацам вместо повторного использования оригинального List, который продолжал бы тот же счётчик.
Как создать маркированный или нумерованный список с нуля?
Используйте ListFormat.ApplyBulletDefault() или ApplyNumberDefault() для стандартного форматирования Word, либо ListCollection.Add(listTemplate) со значением ListTemplate, чтобы начать с предопределённого формата и настроить полученный List.ListLevels оттуда.
Как получить числовой формат вроде “1)” вместо “1.”?
Установите ListLevel.NumberFormat на соответствующем уровне в требуемую строку формата, а также NumberStyle для самого стиля нумерации.