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

WPF::将RibbonComboBox的样式设置为与RibbonGallery不同的样式,wpf,ribbon,ribbon-control,ribboncontrolslibrary,windows-ribbon-framework,Wpf,Ribbon,Ribbon Control,Ribboncontrolslibrary,Windows Ribbon Framework,我有一个用于设置字体大小的RibbonComboBox。它有一个列有各种字体大小的RibbonGallery,显示在相应的FontSize中: <r:RibbonComboBox DataContext="{x:Static vm:RibbonDataModel.FontSizeComboBoxData}" SelectionBoxWidth="30"> <r:RibbonGallery MaxColumnCount="1"

我有一个用于设置字体大小的
RibbonComboBox
。它有一个列有各种字体大小的
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>

编辑这是我的视图模型:

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>;
        }
     }
  }
}
公共静态RibbonDataModel
{
公共静态GalleryData FontSizeComboxData
{
得到
{
锁定(锁定对象)
{
const string key=“Font Size”;
如果(!DataCollection.ContainsKey(键))
{
var值=新的GalleryData
{
Command=HtmlDocumentCommands.ChangeFontSize,
Label=“更改字体大小”,
ToolTipDescription=“将字体设置为特定大小。”,
ToolTipTitle=“更改字体大小”,
};
var fontSizes=新GalleryCategoryData();
var i=9.0;

虽然(我我建议您使用库而不是Microsoft Ribbon(因为它们有很多缺陷,维护不好,只支持旧样式,请相信我,这将为您节省很多麻烦)

然后您可以简单地使用以下代码:

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

并得到预期的结果:


RibbonComboBox
使用
内容演示器
显示您在
RibbonGallery
中选择的项目。 此外,
ContentPresenter
采用与您在
RibbonGallery
中声明的相同的
ItemTemplate
。 这是你问题的“核心”原因

因此,您可以选择两种解决方案来解决问题

第一个解决方案(最快的解决方案)

您只需将RibbonComboBox的
IsEditable
属性设置为“true”。这样,RibbonComboBox就可以在不使用任何ItemTemplate的情况下用文本框替换ContentPresenter。这样字体的大小就合适了

第二种解决方案(最好的解决方案)

由于ItemTemplate同时从RibbonComboBox的ContentPresenter和RibbonGallery中使用,因此我们可以尝试解决这个问题。唯一的区别是,当DataTemplate放置在RibbonGallery中时,它的父项是
RibbonGallery项
。 因此,如果其父项不是
RibbonGalleryItem
,您会自动知道DataTemplate被放置在ContentPresenter中。 您可以通过编写一个简单的
DataTrigger
来处理这种情况。 让我们看看代码中的所有内容

我编写了一个简化的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;
            }
        }
    }
}
命名空间WpfApplication1
{
公营班级人数
{
私有静态FontSizes实例=新FontSizes();
私有列表值=新列表();
公共图书馆
{
双i=9.0;

虽然(我可以请你发布你的ViewModel代码吗?按要求发布。这正是我想要的。切换到Fluent.Ribbon可能会给我省去一些麻烦,但获得批准使用第三方库并不是一项简单的任务。目前这不是一个选项。我已经在使用Microsoft的Ribbon。要使用Fluent ribbon组件,我需要交换整个功能区吗?这并不完全容易,而且取决于您使用它的范围,可能需要更长的时间,但是对于我们的应用程序,大约有6个不同的功能区,它需要大约3-5天,但它也解决了许多与microsoft功能区相关的错误
<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>