La mia domanda è fondamentalmente this one. Ho pensato che sarebbe stato utile fornire ulteriori informazioni e codice che rendessero più semplice riprodurre il problema.Come selezionare l'oggetto SelectedItem di RibbonComboBox
Lavorare con Microsoft.Windows.Controls.Ribbon.RibbonComboBox dallo RibbonControlsLibrary sembra di camminare in una grande palude piena di bug, non qualcosa che si fa se si sa come aggirarla.
Anywho. Il problema più grande che ho riscontrato era l'associazione del mio SelectedItem.
Quanto segue è quello che ho iniziato con (dopo aver scoperto RibbonGallery?). Avere ItemsSource e SelectedItem su sottoelementi del ComboBox e nemmeno sullo stesso livello mi ha già dato l'heebie-jeebies, ma sembra essere corretto.
Nell'app di esempio, sto impostando SelectedItem nel costruttore di ViewModel. Tuttavia, quando si esegue l'app, non viene visualizzato SelectedItem. Anche il progettista VS mostra correttamente "seconda opzione"!
Esecuzione app: VS progettista:
Quando il debug il setter SelectedItem, si noterà più passaggi. Dopo averlo impostato per la prima volta su "seconda opzione" nel ctor (1, vedere il registro di debug sotto), verrà ripristinato su null (2) (per codice esterno, conto nel controllo stesso). Quando si apre il menu a discesa nell'interfaccia utente, verrà nuovamente impostato su null (3), quindi quando si seleziona un valore, due volte su questo valore (4,5). Ho selezionato "seconda opzione", quindi ho ripetuto la procedura con "prima opzione" (6-9). Ciò ha prodotto il seguente registro (ignorando le mille e un'eccezioni vincolanti dal controllo del nastro ...):
Il grosso problema, ovviamente, è (2), che è il ripristino mia selezione iniziale. Sembra che quando il controllo viene mostrato la prima volta, viene resettato. Una soluzione molto brutta sarebbe quella di impostare il valore con un timer. Impostarlo nell'evento Loaded del controllo utente funziona per me in questa app di esempio, ma nella mia app realistica più pesante, non è così. Ad ogni modo, tutto ciò sembra sbagliato. Qualcuno conosce una soluzione migliore?
Xaml:
<UserControl x:Class="WpfApplication1.RibbonComboBoxDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:r="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:ViewModel />
</UserControl.DataContext>
<Grid>
<r:Ribbon >
<r:RibbonTab Header="First Tab">
<r:RibbonGroup Header="Group">
<r:RibbonComboBox >
<r:RibbonGallery SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<r:RibbonGalleryCategory ItemsSource="{Binding Controls}" DisplayMemberPath="Caption" />
</r:RibbonGallery>
</r:RibbonComboBox>
</r:RibbonGroup>
</r:RibbonTab>
<r:RibbonTab Header="Second Tab" />
</r:Ribbon>
</Grid>
</UserControl>
ViewModel:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<ControlBaseModel> Controls { get; private set; }
private ControlBaseModel _selectedItem;
public ControlBaseModel SelectedItem { get { return _selectedItem; } set { LogSelectedItemChange(value); _selectedItem = value; OnPropertyChanged("SelectedItem"); } }
public ViewModel()
{
this.Controls = new ObservableCollection<ControlBaseModel>();
this.Controls.Add(new ControlBaseModel() { Caption = "first option" });
this.Controls.Add(new ControlBaseModel() { Caption = "second option" });
this.SelectedItem = this.Controls[1]; // set to second option
}
int i = 0;
private void LogSelectedItemChange(ControlBaseModel value)
{
i++;
string setObject = "null";
if (value != null)
{
setObject = value.Caption;
}
Debug.WriteLine(string.Format("{0}: SelectedItem.set(): {1}", i, setObject));
}
}
public class ControlBaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _name;
public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } }
private string _caption;
public string Caption { get { return _caption; } set { _caption = value; OnPropertyChanged("Caption"); } }
}
}
Tu mi ha salvato una quantità enorme di tempo ...Grazie mille !!! –