Telerik blogs

In this post we will go through a scenario for databinding the RadToolBar control.

Here is the end result:

And the demo project with everything included:

ToolBarMVVM.zip

How to databind the ToolBar?

The ToolBar is an ItemsControl and can be databound to any IEnumerable, but it is preferable to bind it to an observable collection since any changes in it will be reflected by the ToolBar. Since there is no ToolBarItem, because ToolBar may contain variety of other controls, we will use DataTemplateSelector class to help us determine the template for each item inside the ToolBar:

public class ToolBarTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is ButtonViewModel)
            {
                return ButtonTemplate;
            }
            else if (item is TextBoxViewModel)
            {
                return TextBoxTemplate;
            }
            else if (item is SeparatorViewModel)
            {
                return SeparatorTemplate;
            }
  
            return null;
        }
  
        public DataTemplate ButtonTemplate
        {
            get;
            set;
        }
  
        public DataTemplate TextBoxTemplate
        {
            get;
            set;
        }
  
        public DataTemplate SeparatorTemplate
        {
            get;
            set;
        }
    }

We should assign an instance of this class to the ItemTemplateSelector property of the ToolBar:

<UserControl.Resources>
    <templateSelector:ToolBarTemplateSelector   x:Key="ToolBarTemplateSelector" 
                                   ButtonTemplate="{StaticResource ButtonTemplate}"
                                   TextBoxTemplate="{StaticResource TextBoxTemplate}"
                                   SeparatorTemplate="{StaticResource SeparatorTemplate}"/>
</UserControl.Resources>
 
<telerik:RadToolBar ItemTemplateSelector="{StaticResource ToolBarTemplateSelector}" />

Having this DataTemplateSelector class we should just define the templates for the different ViewModel classes:

          <DataTemplate x:Key="ButtonTemplate"
            <Button Style="{StaticResource ToolBarButton}"
                <Button.Content
                    <StackPanel Orientation="Horizontal"
                        <Image Source="{Binding ImagePath}" Margin="0 0 2 0"/> 
                        <TextBlock Text="{Binding Text}" /> 
                    </StackPanel
                </Button.Content
            </Button
        </DataTemplate
        <DataTemplate x:Key="TextBoxTemplate"
            <TextBox Style="{StaticResource ToolBarTextBox}" Width="100" Text="{Binding Text, Mode=TwoWay}" /> 
        </DataTemplate
        <DataTemplate x:Key="SeparatorTemplate"
            <telerik:RadToolBarSeparator Style="{StaticResource ToolBarSeparator}" /> 
        </DataTemplate>

Now we can simply define the MainViewModel class where we generate the collection of items, which we will use as an ItemSource collection for the ToolBar:

public class MainViewModel : BaseViewModel
    {
        public ObservableCollection<BaseViewModel> Items
        {
            get;
            private set;
        }
  
        public MainViewModel()
        {
            Items = GenerateToolBarItems();
        }
  
        private ObservableCollection<BaseViewModel> GenerateToolBarItems()
        {
            ButtonViewModel newMailButton = new ButtonViewModel() { ImagePath = "../Images/newMailMessage.png" };
            SeparatorViewModel separator = new SeparatorViewModel();
            ButtonViewModel printButton = new ButtonViewModel() { ImagePath = "../Images/print.png" };
            ButtonViewModel moveToFolderButton = new ButtonViewModel() { ImagePath = "../Images/moveToFolder.png" };
            ButtonViewModel deleteButton = new ButtonViewModel() { ImagePath = "../Images/delete.png" };
            ButtonViewModel replyButton = new ButtonViewModel() { ImagePath = "../Images/reply.png", Text = "Reply" };
            ButtonViewModel categorizeButton = new ButtonViewModel() { ImagePath = "../Images/categorize.png" };
            ButtonViewModel followUpButton = new ButtonViewModel() { ImagePath = "../Images/followUp.png" };
            ButtonViewModel sendReceiveButton = new ButtonViewModel() { ImagePath = "../Images/sendReceive.png", Text = "Send/Receive" };
            TextBoxViewModel textBox = new TextBoxViewModel() { Text = "Search..." };
            ButtonViewModel searchButton = new ButtonViewModel() { ImagePath = "../Images/google.png", Text = "Search" };
            ButtonViewModel helpButton = new ButtonViewModel() { ImagePath = "../Images/help.png", Text = "Help" };
  
            ObservableCollection<BaseViewModel> items = new ObservableCollection<BaseViewModel>();
  
            items.Add(newMailButton);
            items.Add(separator);
            items.Add(printButton);
            items.Add(moveToFolderButton);
            items.Add(deleteButton);
            items.Add(separator);
            items.Add(replyButton);
            items.Add(separator);
            items.Add(categorizeButton);
            items.Add(followUpButton);
            items.Add(separator);
            items.Add(sendReceiveButton);
            items.Add(textBox);
            items.Add(searchButton);
            items.Add(helpButton);
  
            return items;
        }
    }

We need to instantiate it in XAML and assign it as a DataContext of the ToolBar:

<UserControl.Resources
    <viewModel:MainViewModel x:Key="mainViewModel" />
</UserControl.Resources
   
<telerik:RadToolBar ItemTemplateSelector="{StaticResource ToolBarTemplateSelector}" />
  
<telerik:RadToolBar DataContext="{StaticResource mainViewModel}" ItemsSource="{Binding Items}" />

In order to make the items look better in the ToolBar we can make custom styles, which for simplicity I will not show here, but you can see them in the demo project.

I hope you will be able to use this idea in your projects.


About the Author

Valio Stoychev

Valentin Stoychev (@ValioStoychev) for long has been part of Telerik and worked on almost every UI suite that came out of Telerik. Valio now works as a Product Manager and strives to make every customer a successful customer.

 

Comments

Comments are disabled in preview mode.