7

Ich habe eine RibbonComboBox, die verwendet wird, um Schriftgrößen festzulegen. Es hat eine RibbonGallery, die die verschiedenen Schriftgrößen auflistet, in der entsprechenden FontSize angezeigt:WPF :: Styling der RibbonComboBox anders als die RibbonGallery

<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 Hier ist meine 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>; 
     } 
    } 
    } 
} 

Alles funktioniert wie erwartet, aber nachdem ich wählen Sie einen Artikel aus der Galerie, es erscheint in der RibbonComboBox mit der gleichen großen (oder winzigen) FontSize wie es in der Galerie verwendet.

Wie kann ich die FontSize des ausgewählten Elements auf den Standard "zurücksetzen", wenn es in der RibbonComboBox angezeigt wird?

+0

Können Sie bitte Ihren ViewModel-Code posten? –

+0

Veröffentlicht wie angefordert. –

Antwort

5

Die RibbonComboBox ein ContentPresenter verwendet das Element, das Sie in den RibbonGallery wählen zu zeigen. Darüber hinaus übernimmt die ContentPresenter die gleiche ItemTemplate, die Sie in der RibbonGallery deklariert haben. Dies ist der "Kern" Grund Ihres Problems.

So können Sie zwischen zwei Lösungen zur Problemumgehung wählen.

erste Lösung (die schnellste)

Sie können einfach stellen Sie die IsEditable Eigenschaft Ihres RibbonComboBox auf "true". Auf diese Weise ersetzt die RibbonComboBox den ContentPresenter durch eine TextBox, ohne ein ItemTemplate zu verwenden. Dann wird die Schriftart die richtige Größe haben.

zweite Lösung (die beste IMHO)

Da die ItemTemplate von beiden den Content des RibbonComboBox bei derselben verwendet werden und die Ribbon, ist es der Punkt, wo wir versuchen können, das Problem zu lösen. Der einzige Unterschied besteht darin, dass wenn das DataTemplate in der RibbonGallery platziert wird, das übergeordnete Element ein RibbonGalleryItem ist. Wenn also das übergeordnete Element kein RibbonGalleryItem ist, wissen Sie automatisch, dass das DataTemplate im ContentPresenter platziert ist. Sie können diese Situation umgehen, indem Sie eine einfache DataTrigger schreiben. Lassen Sie uns alle im Code sehen.

schrieb ich eine vereinfachte Ansichtsmodell:

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

Dann ist meine Ansicht:

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

Wie Sie die Datatrigger ist die „Komponente“ sehen kann, die die „schmutzige Arbeit“ macht.

Jetzt müssen Sie nur noch Ihre Meinung darüber, welche Lösung Sie bevorzugen.

+0

Das ist * genau * was ich gesucht habe. –

1

Ich würde Ihnen empfehlen, die Fluent.Ribbon Bibliothek anstelle der Microsoft Ribbons zu verwenden (wie sie sind sehr buggy, nicht gut gepflegt und nur alte Stile unterstützen, wirklich Vertrauen Sie mir auf diesem einen es wird Ihnen nur viel Ärger ersparen).

Dann einfach können Sie diesen Code verwenden:

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

Und um das gewünschte Ergebnis erhalten:

enter image description here

+0

Während der Wechsel zu Fluent.Ribbon mir einige Probleme ersparen kann, ist es keine leichte Aufgabe, die Genehmigung für die Arbeit mit einer Drittanbieter-Bibliothek zu bekommen. Dies ist zu diesem Zeitpunkt einfach keine Option. –

+0

Ich arbeite bereits mit Microsoft Ribbon. Um die Fluent-Farbbandkomponente zu verwenden, muss ich das gesamte Farbband austauschen? –

+0

Es ist nicht ganz einfach, und abhängig davon, wie weit Sie es verwenden, kann es eine längere Zeit dauern, aber für unsere Anwendung mit etwa 6 verschiedenen Bändern dauerte es etwa 3-5 Tage, aber es hat auch viele der Fehler behoben im Zusammenhang mit Microsoft Ribbon – Staeff