2013-03-21 28 views
8

Soruma temel olarak this one. Yine de, sorunu yeniden üretmeyi kolaylaştıran bazı daha fazla bilgi ve kod sağlamaya yardımcı olacağını düşündüm.RibbonComboBox'ın SelectedItem'ine nasıl bağlanır?

RibbonControlsLibrary'dan Microsoft.Windows.Controls.Ribbon.RibbonComboBox ile çalışmak, etrafınızdaki bir yolu biliyorsanız, bir şeylerle dolu büyük bir bataklıktan yürümek gibi hissettirir.

Anywho. Karşılaştığım en büyük sorun, SelectedItem'imi veriyorum.

Başladığım şudur (RibbonGallery? hakkında öğrendikten sonra). ComboBox'un subelement'lerinde ItemsSource ve SelectedItem'e sahip olmak ve hatta aynı seviyede bile bana heebie-jeebies verdi, ama bu doğru görünüyor.

Örnek uygulamada, SelectedItem'i ViewModel yapıcısında ayarlıyorum. Ancak, uygulamayı çalıştırırken, SelectedItem gösterilmez. VS tasarımcısı bile "ikinci seçenek" gösteriyor!

Running uygulaması: Running App VS tasarımcısı: Visual Studio Designer

SelectedItem ayarlayıcı ayıklama, birden geçer göreceksiniz. Ctorda "ikinci seçenek" e ilk kez ayarladıktan sonra (1, aşağıdaki hata ayıklama günlüğüne bakın), null (2) 'e sıfırlanır (harici kodla, kontrolün kendisinde olduğunu düşünüyorum). Kullanıcı arayüzündeki açılır menüyü açarken, tekrar (3), ardından bir değer seçerken, bu değere iki kez (4,5) ayarlanır. "İkinci seçenek" seçeneğini seçtikten sonra prosedürü "ilk seçenek" (6-9) ile tekrarladım. Bu (şerit kontrolü ... den bin bir bağlanma durumları görmezden) Aşağıdaki günlük oluşturdu:

enter image description here

besbelli (2), benim ilk seçim sıfırlıyor edilir büyük sorun. Kontrol ilk kez gösterildiğinde, sıfırlanır. Değeri bir zamanlayıcıyla ayarlamak çok çirkin bir çözüm olacaktır. Kullanıcı kontrolünün Loaded olayı olarak ayarlanması benim için bu örnek uygulamada çalışır, ancak benim daha ağır gerçek hayattaki uygulamasında, bunu yapmaz. Her neyse, hepsi yanlış geliyor. Daha iyi bir çözüm bilen var mı?

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

cevap

5

ComboBox SelectedItem benim uygulamada null sıfırlanır önce yüklenen olay oluştuğunu Görünüm/UserControl ComboBox yüklenen olay aslında iken iki kez ateş, ikinci kez "geç" yeterli. Bu yüzden daha iyi bir için memnuniyetle hendek olacak benim şimdiki çözüm şudur ki:

<r:RibbonComboBox> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Loaded"> 
      <i:InvokeCommandAction Command="{Binding LoadedCommand}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <r:RibbonGallery SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
     <r:RibbonGalleryCategory ItemsSource="{Binding Controls}" DisplayMemberPath="Caption"/> 
    </r:RibbonGallery> 
</r:RibbonComboBox> 

ViewModel:

Sadece standart ComboBox kullanarak sona erdi
private ControlBaseModel _lastNonNullSelectedItem; 

public ObservableCollection<ControlBaseModel> Controls { get; private set; } 

private ControlBaseModel _selectedItem; 
public ControlBaseModel SelectedItem 
{ 
    get { return _selectedItem; } 
    set 
    { 
     if (value != null) { _lastNonNullSelectedItem = value; } 
     _selectedItem = value; 
     OnPropertyChanged("SelectedItem"); 
    } 
} 
public ICommand LoadedCommand { get; private set; } 


public ViewModel() 
{ 
    this.Controls = new ObservableCollection<ControlBaseModel>(); 
    this.LoadedCommand = new ActionCommand(OnLoaded); // ActionCommand: simple implementation of ICommand 

    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 
} 

private void OnLoaded() 
{ 
    this.SelectedItem = _lastNonNullSelectedItem; 
} 
+0

kullanın ...Çok teşekkürler !!! –

2

.

<ComboBox SelectedItem="{Binding Item}" ItemsSource="{Binding Items}"/> 

Eğer RibbonComboBox aynı (çok benzeyen) tarzı istiyorsanız, Bana zaman muazzam miktarda kurtardı

<ComboBox IsEditable="True" IsReadOnly="True" SelectedItem="{Binding Item}" ItemsSource="{Binding Items}"/> 
İlgili konular