7

Ho un RibbonComboBox utilizzato per impostare le dimensioni dei caratteri. Ha un RibbonGallery che elenca le varie dimensioni dei caratteri, visualizzati nella appropriata FontSize:WPF :: Styling del RibbonComboBox in modo diverso rispetto a 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 Ecco il mio 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>; 
     } 
    } 
    } 
} 

tutto funziona come previsto, ma dopo seleziono un elemento dalla galleria, appare nello RibbonComboBox con lo stesso enorme (o minuscolo) FontSize utilizzato nella galleria.

Come è possibile "ripristinare" lo FontSize dell'elemento selezionato su quello predefinito quando viene visualizzato nello RibbonComboBox?

+0

Puoi pubblicare il codice di ViewModel, per favore? –

+0

Pubblicato come richiesto. –

risposta

5

Il RibbonComboBox utilizza un ContentPresenter di mostrare l'articolo selezionato nel RibbonGallery. Inoltre lo ContentPresenter adotta lo stesso ItemTemplate dichiarato in RibbonGallery. Questa è la ragione "principale" del tuo problema.

Quindi è possibile scegliere tra due soluzioni per risolvere il problema.

prima soluzione (il più veloce)

si può semplicemente impostare la proprietà IsEditable del RibbonComboBox su "true". In questo modo RibbonComboBox sostituisce ContentPresenter con un TextBox, senza utilizzare ItemTemplate. Quindi il carattere avrà la giusta dimensione.

seconda soluzione (il migliore IMHO)

Dal momento che l'ItemTemplate viene utilizzato allo stesso sia ContentPresenter del RibbonComboBox e la RibbonGallery, è il punto in cui possiamo cercare di risolvere il problema. La grande differenza è che quando DataTemplate è inserito all'interno di RibbonGallery, il suo genitore è un RibbonGalleryItem. Quindi se il genitore non è un RibbonGalleryItem, si sa automaticamente che DataTemplate è collocato all'interno di ContentPresenter. È possibile gestire questa situazione scrivendo un semplice DataTrigger. Vediamo tutto nel codice.

ho scritto una ViewModel semplificata:

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

Allora questo è il mio Vista:

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

Come si può vedere il DataTrigger è la "componente" che rende il "lavoro sporco".

Ora hai solo bisogno di farti un'idea della soluzione che preferisci.

+0

Questo è * esattamente * quello che stavo cercando. –

1

Vorrei consigliarti di usare la libreria Fluent.Ribbon invece dei Microsoft Ribbons (dato che sono molto bacati, non ben gestiti e supportano solo i vecchi stili, fidati di me su questo, ma ti risparmieranno solo molti problemi).

Quindi è sufficiente possibile utilizzare questo codice:

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

E ottenere il risultato desiderato:

enter image description here

+0

Mentre passare a Fluent.Ribbon potrebbe salvarmi qualche problema, ottenere l'approvazione per lavorare con una libreria di terze parti non è un compito semplice. Questo semplicemente non è un'opzione in questo frangente. –

+0

Sto già lavorando con la barra multifunzione di Microsoft. Per utilizzare il componente nastro Fluent, è necessario sostituire l'intero nastro? –

+0

Non è del tutto semplice, e in base a quale estensione si sta utilizzando può richiedere più tempo, ma per la nostra applicazione con circa 6 diversi nastri ci sono voluti circa 3-5 giorni, ma ha anche risolto molti dei bug che avevamo relativo al nastro di Microsoft – Staeff

Problemi correlati