Meine Frage ist im Grunde this one. Ich dachte, es würde helfen, mehr Informationen und Code zur Verfügung zu stellen, der es einfacher macht, das Problem zu reproduzieren.Gewusst wie: Databind SelectedItem of RibbonComboBox
Die Arbeit mit der Microsoft.Windows.Controls.Ribbon.RibbonComboBox aus der RibbonControlsLibrary fühlt sich an wie ein Spaziergang durch einen großen Sumpf voller Bugs, nicht etwas, was man tut, wenn man einen Weg kennt.
Anywho. Das größte Problem, auf das ich stieß, war die Datenbindung mit SelectedItem.
Das Folgende ist, was ich begann mit (nachdem ich über RibbonGallery erfahren?). ItemsSource und SelectedItem auf Unterelementen der ComboBox und nicht einmal auf dem gleichen Level zu haben gab mir schon die Heebie-Jeebies, aber das scheint richtig zu sein.
In der Beispielanwendung setze ich das SelectedItem im Konstruktor des ViewModel. Beim Ausführen der App wird jedoch kein SelectedItem angezeigt. Sogar der VS-Designer zeigt "zweite Option" korrekt an!
Lauf App: VS Designer:
Wenn die Setter SelectedItem debuggen, werden Sie mehrere Durchgänge bemerken. Nachdem es das erste Mal auf "zweite Option" im ctor gesetzt wurde (1, siehe Debugprotokoll unten), wird es auf null (2) zurückgesetzt (nach externem Code rechne ich mit dem Steuerelement selbst). Wenn Sie das Dropdown-Menü in der Benutzeroberfläche öffnen, wird es wieder auf Null gesetzt (3), und wenn Sie einen Wert auswählen, wird dieser Wert zweimal auf 4,5 gesetzt. Ich wählte "zweite Option" und wiederholte dann die Prozedur mit "erste Option" (6-9). Dies ergab die folgenden log (die einstausendein Bindung Ausnahmen von der Band Kontrolle zu ignorieren ...):
Das große Problem offensichtlich ist (2), die meine erste Auswahl wird zurückgesetzt wird. Sieht so aus, als wenn das Steuerelement das erste Mal angezeigt wird, wird es zurückgesetzt. Ein sehr hässlicher Workaround wäre, den Wert durch einen Timer zu setzen. Die Einstellung im Loaded-Ereignis des Benutzersteuerelements funktioniert für mich in dieser Beispiel-App, in meiner schwereren Real-Life-App jedoch nicht. Jedenfalls fühlt sich das alles falsch an. Kennt jemand eine bessere Lösung?
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>
Ansichtsmodell:
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"); } }
}
}
Du hast mich gerettet eine enorme Menge an Zeit ...Vielen Dank !!! –