8

我有一个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>;
        }
     }
  }
}

一切都按预期工作,但是在我从画廊中选择一个项目后,它会显示在RibbonComboBox与画廊中相同的巨大(或微小)FontSize中。

当所选项目显示在 中时,如何将其“重置”FontSize为默认值RibbonComboBox

4

2 回答 2

5

使用RibbonComboBoxaContentPresenter显示您在 中选择的项目RibbonGallery。此外,ContentPresenter采用与ItemTemplate您在RibbonGallery. 这是您问题的“核心”原因。

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

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

您可以简单地将IsEditableRibbonComboBox 的属性设置为“true”。这样,RibbonComboBox 将 ContentPresenter 替换为 TextBox,而不使用任何 ItemTemplate。然后字体将具有正确的大小。

第二个解决方案(最好的一个恕我直言)

由于在 RibbonComboBox 的 ContentPresenter 和 RibbonGallery 中同时使用了 ItemTemplate,因此我们可以尝试解决问题。唯一的区别是,当 DataTemplate 放在 RibbonGallery 中时,它的父级是RibbonGalleryItem. 因此,如果它的父级不是 a 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;
            }
        }
    }
}

然后这是我的观点:

<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>

如您所见,DataTrigger 是“脏工作”的“组件”。

现在您只需要确定您喜欢哪种解决方案即可。

于 2015-04-22T08:21:57.237 回答
2

我建议您使用Fluent.Ribbon库而不是 Microsoft Ribbons(因为它们有很多缺陷,维护不善并且只支持旧样式,真的相信我,它只会为您省去很多麻烦)。

然后你可以简单地使用这个代码:

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

并得到想要的结果:

在此处输入图像描述

于 2015-04-21T14:56:34.957 回答