If you have taken a look at the blog post about the new features introduced in the latest Q1 2011 and have taken a liking to the multilevel lists, you should definitely read this one. It will give you some insight on the usage of the options that come out of box and some information on how you can extend them to suit the purposes of your project.

In case you are in the habit of starting reading from the end, you can preview the Silverlight demo to see the lists in action. You should note that there are buttons both in the RibbonBar and in the SelectionMiniToolBar for toggling lists on and off. You can also easily convert lists from one type to another using the list-style gallery from the Paragraph RibbonGroup in the Home Tab. Changing the list level at which a paragraph appears is done fairly simple, too, using the buttons with the cute arrows or the key-bindings that trigger the corresponding commands (Tab for increasing the indent and Shift + Tab for decreasing it). You can have up to 9 levels with the default lists, similarly to the ones in MS Word. Here is an example:

clip_image002

Lists can be created and inserted into a document programmatically just as easily. All you need to do is create a list and some paragraphs and add the paragraphs to the list at the list level you wish them to appear. The numbers and the bullet types are automatically taken care of for you. Here is a code-snippet to get you started:

private RadDocument CreateDocumentWithMultiLevelList()
{
   
RadDocument document = new RadDocument();
   
Section section = new Section();

   
DocumentList list = new DocumentList(DefaultListStyles.NumberedParenthesis);
   
for (int i = 0; i < 9; i++)
   
{
       
Paragraph listItemParagraph = new Paragraph();
       
Span listItemSpan = new Span("Text at level " + (i + 1));
       
listItemParagraph.Inlines.Add(listItemSpan);
       
list.AddParagraph(listItemParagraph, i);
       
section.Blocks.Add(listItemParagraph);
   
}
   
for (int i = 8; i >= 0; i--)
   
{
       
Paragraph listItemParagraph = new Paragraph();
       
Span listItemSpan = new Span("Text at level " + (i + 1));
       
listItemParagraph.Inlines.Add(listItemSpan);
       
list.AddParagraph(listItemParagraph, i);
       
section.Blocks.Add(listItemParagraph);
   
}
   
document.Sections.Add(section);
   
return document;

}

The result:

clip_image002[7]

You have predefined list styles at your disposal (the ones that appear in the list library) – Bulleted, Numbered, NumberedHierarchical (the one from the first screenshot), NumberedParenthesis (second screenshot) and None – which if used on paragraphs in a list will exclude them from the list.

The default list styles come handy, as they require little to no effort on your part, but if you find them plain, you are more than welcome to create your own using the API. You can quite easily create a bulleted list using bullets defined by you, a numbered list which uses Roman digits, or one that uses Arabic numbers, but does not include the number of the previous list item which is of a smaller level.

The functionality you need to use is located in the ListStyle and ListLevelStyle classes. Here are the steps you need to follow in order to create a new list:

  1. Create a new instance of ListStyle. You can see that the ListStyle class has a static readonly field ListLevels that keeps the number of levels that the default lists can have (9). It is recommended that you allow your lists to have that many levels, too, for uniformity and for prettier conversion between list types. You are, of course, free to have as many levels as you like, which will reflect on how much the users will be able to indent the paragraphs.
  2. Define a ListLevelStyle for each level depending on the way that you wish your bullet or number to appear, and add it to the Levels property which is of type ObservableCollection<ListLevelStyle>. The customization options are presented by the following properties:
    1. StartingIndex – should the list start at 0 or 1 for example;
    2. FontFamily – the font family you wish the numbers/bullets to appear. This is particularly useful, if you wish to use the “o” in Courier New or an item from Wingdings for a bullet in your list;
    3. NumberingFormat – the numbering format that you wish to use. The available numbering formats are defined as an enum called ListNumberingFormat. The options provided are: Bullet, Decimal, UpperLetter, LowerLetter, UpperRoman and LowerRoman.
    4. The LevelText is the string format that you would like the numbers/bullets to appear at each level. Using this property, you can set if you wish the list item to contain the numbers of its predecessors (like in the NumberedHierarchical list style) or not (like in the other predefined list styles).

So much for the theory, let’s see how a list can be created in practice. Say you wish to have a numbered list that has UpperRoman letters at all levels and each level includes the number of the item that is its predecessor. Here is the code to achieve this:

public void RegisterUpperRomanHierarchicalListStyle()
{

    ListStyle upperRomanHierarchical = new ListStyle();
   
upperRomanHierarchical.Levels = new ObservableCollection<ListLevelStyle>();
   
for (int i = 0; i < ListStyle.ListLevels; i++)
   
{
       
StringBuilder levelText = new StringBuilder();
       
for (int j = 0; j < i + 1; ++j)
       
{
           
levelText.Append("{" + j + "}.");
       
}
       
Hierarchical.Levels.Add(new ListLevelStyle()
       
{
           
StartingIndex = 1,
           
NumberingFormat = ListNumberingFormat.UpperRoman,
           
LevelText = levelText.ToString()
       
});
   
}
   
DefaultListStyles.RegisteredStyles.Add("UpperRomanHierarchical", upperRomanHierarchical);

}

Since the change in the list style is performed through a command triggered through the RadRichTextBoxRibbonUI, you can utilize this new list type just by adding a line in the already generated XAML, namely:

<telerik:RadGallery ItemHeight="88" ItemWidth="88" telerik:RadRichTextBoxRibbonUI.RichTextCommand="{Binding Path=ChangeListStyleCommand}" ViewportHeight="176" ViewportWidth="266">
   
<telerik:RadGalleryItem Image="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/MultilevelListNone.png" Tag="None" />
    <
telerik:RadGalleryItem Image="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/MultilevelListBulleted.png" Tag="Bulleted" />
    <
telerik:RadGalleryItem Image="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/MultilevelListNumbered.png" Tag="Numbered" />
    <
telerik:RadGalleryItem Image="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/MultilevelListNumberedParenthesis.png" Tag="NumberedParenthesis" />
    <
telerik:RadGalleryItem Image="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/MultilevelListNumberedHierarchical.png" Tag="NumberedHierarchical" />
    <
telerik:RadGalleryItem Image="Images/ UpperRomanHierarchical.png" Tag="UpperRomanHierarchical" />

</telerik:RadGallery>

This code will create and utilize a list that would look like this:

clip_image001

If you wish to register a new bulleted list, it is even easier. You can choose the characters you wish to appear at each level like in the following snippet:

public void RegisterSymbolBulletedListStyle()
{
   
ListStyle symbolBulleted = new ListStyle();
   
Tuple<string, FontFamily>[] listLevelSymbols = new Tuple<string, FontFamily>[] {
   
new Tuple<string, FontFamily>("v", new FontFamily("Wingdings")),
   
new Tuple<string, FontFamily>("l", new FontFamily("Wingdings")),
   
new Tuple<string, FontFamily>("J", new FontFamily("Wingdings")),
   
};
   
   
symbolBulleted.Levels = new ObservableCollection<ListLevelStyle>();

   
for (int i = 0; i < ListStyle.ListLevels; i++)
   
{
       
var style = listLevelSymbols[i % 3];
       
symbolBulleted.Levels.Add(new ListLevelStyle()
       
{
           
StartingIndex = 1,
           
NumberingFormat = ListNumberingFormat.Bullet,
           
LevelText = style.Item1,
           
FontFamily = style.Item2
       
});
   
}
   
DefaultListStyles.RegisteredStyles.Add("SymbolBulleted", symbolBulleted);

}

The result:

image

You can find the source code (a fully-functional example with an extended RibbonGalery) attached to this blog post.

Feedback would be, as always, greatly appreciated.

 

CustomListStyles.zip


About the Author

Iva Toteva

is a software developer and works closely with clients to assist them in utilizing the RadControls they use for the purposes of their application. The controls in her domain include RadRichTextBox, RadSpreadsheet and RadPdfViewer.

Related Posts

Comments

Comments are disabled in preview mode.