简体   繁体   English

WPF ::将RibbonComboBox设置为与RibbonGallery不同的样式

[英]WPF :: Styling the RibbonComboBox Differently Than The RibbonGallery

I have a RibbonComboBox that is used to set font sizes. 我有一个用于设置字体大小的RibbonComboBox It has a RibbonGallery that lists the various font sizes, displayed in the appropriate FontSize : 它有一个RibbonGallery ,列出了各种字体大小,显示在相应的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: 编辑这是我的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 I select an item from the gallery, it shows up in the RibbonComboBox with the same huge (or tiny) FontSize as it uses in the gallery. 一切都按预期工作,但在我从图库中选择一个项目后,它会在RibbonComboBox显示与在图库中使用的相同的巨大(或微小) FontSize

How can I "reset" the FontSize of the selected item to the default when it's displayed in the RibbonComboBox ? 当在RibbonComboBox显示时,如何将所选项目的FontSize “重置”为默认值?

The RibbonComboBox uses a ContentPresenter to show the item you select in the RibbonGallery . RibbonComboBox使用ContentPresenter显示您在RibbonGallery选择的RibbonGallery Moreover the ContentPresenter adopts the same ItemTemplate that you declared in the RibbonGallery . 此外, ContentPresenter采用您在RibbonGallery声明的相同ItemTemplate This is the "core" reason of your problem. 这是您问题的“核心”原因。

So you can choose between two solutions to workaround the problem. 因此,您可以选择两种解决方案来解决问题。

FIRST SOLUTION (the fastest one) 第一个解决方案(最快的解决方案)

You can simply set the IsEditable property of your RibbonComboBox to "true". 您只需将RibbonComboBox的IsEditable属性设置为“true”即可。 In this way the RibbonComboBox replaces the ContentPresenter with a TextBox, without using any ItemTemplate. 通过这种方式,RibbonComboBox用TextBox替换ContentPresenter,而不使用任何ItemTemplate。 Then the font will have the right size. 然后字体将具有正确的大小。

SECOND SOLUTION (the best one IMHO) 第二个解决方案(最好的一个恕我直言)

Since the ItemTemplate is used at the same from both the RibbonComboBox's ContentPresenter and the RibbonGallery, it is the point where we can try to solve the problem. 由于ItemTemplate在RibbonComboBox的ContentPresenter和RibbonGallery中同时使用,因此我们可以尝试解决问题。 The olny difference is that when the DataTemplate is placed inside the RibbonGallery, its parent is a RibbonGalleryItem . olny的区别在于,当DataTemplate放置在RibbonGallery中时,其父级是RibbonGalleryItem So if its parent is not a RibbonGalleryItem , you automatically know that the DataTemplate is placed inside the ContentPresenter. 因此,如果其父级不是RibbonGalleryItem ,则会自动知道DataTemplate放置在ContentPresenter中。 You can handle this situation by writing a simple DataTrigger . 您可以通过编写一个简单的DataTrigger来处理这种情况。 Let's see all in the code. 我们在代码中看到所有内容。

I wrote a simplified ViewModel: 我写了一个简化的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 the DataTrigger is the "component" which makes the "dirty job". 正如您所看到的,DataTrigger是“组件”,它构成了“脏工作”。

Now you just need to make you your mind about which solution you prefer. 现在,您只需要了解自己喜欢哪种解决方案。

I would advise you to use the Fluent.Ribbon library instead of the Microsoft Ribbons (as they are very buggy, not well maintained and only support old styles, really trust me on this one it will just save you much trouble). 我建议你使用Fluent.Ribbon库而不是Microsoft Ribbons(因为它们非常多,没有很好的维护,只支持旧样式,真的相信我这一点,它会省你很多麻烦)。

Then you simply can 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: 并获得所需的结果:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM