WPF :: Styling the RibbonComboBox in a different way than the ribbon gallery

I have a RibbonComboBox that is used to set font sizes. It has a RibbonGallery , which lists the different font sizes displayed in the corresponding FontSize :

 <r:RibbonComboBox DataContext="{x:Static vm:RibbonDataModel.FontSizeComboBoxData}" SelectionBoxWidth="30"> <r:RibbonGallery MaxColumnCount="1" Command="{Binding Command}" CommandParameter="{Binding SelectedItem}"> <r:RibbonGallery.GalleryItemTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding}" FontSize="{Binding}" /> </Grid> </DataTemplate> </r:RibbonGallery.GalleryItemTemplate> </r:RibbonGallery> </r:RibbonComboBox> 

EDIT Here is my ViewModel:

 public static RibbonDataModel { public static GalleryData<object> FontSizeComboBoxData { get { lock (LockObject) { const string key = "Font Size"; if (!DataCollection.ContainsKey(key)) { var value = new GalleryData<object> { Command = HtmlDocumentCommands.ChangeFontSize, Label = "Change Font Size", ToolTipDescription = "Set the font to a specific size.", ToolTipTitle = "Change Font Size", }; var fontSizes = new GalleryCategoryData<object>(); var i = 9.0; while (i <= 30) { fontSizes.GalleryItemDataCollection.Add(i); i += 0.75; } value.CategoryDataCollection.Add(fontSizes); DataCollection[key] = value; } return DataCollection[key] as GalleryData<object>; } } } } 

Everything works as expected, but after selecting an item from the gallery, it appears in the RibbonComboBox with the same huge (or tiny) FontSize as it is used in the gallery.

How can I "reset" FontSize selected item to default when it is displayed in a RibbonComboBox ?

+7
wpf ribbon ribboncontrolslibrary windows-ribbon-framework
source share
2 answers

The RibbonComboBox uses the ContentPresenter to display the item you selected in the RibbonGallery . In addition, ContentPresenter accepts the same ItemTemplate that you specified in RibbonGallery . This is the "root cause" of your problem.

Thus, you can choose one of two solutions to the problem.

FIRST SOLUTION (fastest)

You can simply set the IsEditable property of your RibbonComboBox to true. Thus, the RibbonComboBox replaces the ContentPresenter with a text field without using an ItemTemplate. Then the font will have the right size.

SECOND DECISION (best IMHO)

Since the ItemTemplate is used at the same time from both the RibbonComboBox ContentPresenter and the RibbonGallery, this is the moment when we can try to solve the problem. The difference in olny is that when a DataTemplate is placed inside the RibbonGallery, its parent is the RibbonGalleryItem . Therefore, if its parent is not a RibbonGalleryItem , you automatically know that the DataTemplate is inside the ContentPresenter. You can handle this situation by writing a simple DataTrigger . Let's see everything in the code.

I wrote a simplified ViewModel:

 namespace WpfApplication1 { public class FontSizes { private static FontSizes instance = new FontSizes(); private List<double> values = new List<double>(); public FontSizes() { double i = 9.0; while (i <= 30) { values.Add(i); i += 0.75; } } public IList<double> Values { get { return values; } } public static FontSizes Instance { get { return instance; } } } } 

Then this is my view:

 <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ribbon="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon" xmlns:vm="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300"> <Window.Resources /> <DockPanel> <ribbon:RibbonComboBox Label="Select a font size:" SelectionBoxWidth="62" VerticalAlignment="Center"> <ribbon:RibbonGallery MaxColumnCount="1"> <ribbon:RibbonGalleryCategory DataContext="{x:Static vm:FontSizes.Instance}" ItemsSource="{Binding Path=Values, Mode=OneWay}"> <ribbon:RibbonGalleryCategory.ItemTemplate> <DataTemplate> <Grid> <TextBlock Name="tb" Text="{Binding}" FontSize="{Binding}" /> </Grid> <DataTemplate.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ribbon:RibbonGalleryItem, AncestorLevel=1}}" Value="{x:Null}"> <Setter TargetName="tb" Property="FontSize" Value="12" /> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </ribbon:RibbonGalleryCategory.ItemTemplate> </ribbon:RibbonGalleryCategory> </ribbon:RibbonGallery> </ribbon:RibbonComboBox> </DockPanel> </Window> 

As you can see, DataTrigger is a “component” that does the “dirty work”.

Now you just need to think about which solution you prefer.

+5
source share

I would advise you to use the Fluent.Ribbon library instead of Microsoft tapes (since they are very erroneous, are not supported in good condition and only support the old styles, really trust me on this, it will just save you many problems).

Then you can simply use this code:

 <fluent:ComboBox Header="Font Size" ItemsSource="{Binding FontSizes}"> <fluent:ComboBox.ItemTemplate> <ItemContainerTemplate> <TextBlock FontSize="{Binding }" Text="{Binding }" /> </ItemContainerTemplate> </fluent:ComboBox.ItemTemplate> </fluent:ComboBox> 

And get the desired result:

enter image description here

+1
source share

All Articles