2013-03-21 7 views
8

के चयनित इटैम का डाटाबेस कैसे करें मेरा प्रश्न मूल रूप से this one है। मैंने सोचा कि इससे कुछ और जानकारी और कोड प्रदान करने में मदद मिलेगी जो समस्या को पुन: उत्पन्न करना आसान बनाता है।रिबन ComboBoxBox

माइक्रोसॉफ्ट के साथ काम करना। Windows.Controls.Ribbon.RibbonComboBox RibbonControlsLibrary से बग से भरा एक बड़ा बग के माध्यम से चलने जैसा लगता है, अगर आप इसके आसपास कोई रास्ता नहीं जानते हैं तो ऐसा कुछ नहीं करते हैं।

Anywho। मेरी सबसे बड़ी समस्या का सामना करना मेरे चुने हुए इटैम को डाटाबेस करना था।

निम्नलिखित के साथ मैंने शुरू किया (मुझे रिबन गैलरी?) के बाद पता चला। कॉम्बोबॉक्स के सबलेमेंट्स पर आइटम्ससोर्स और चयनित इटैम रखने के लिए और उसी स्तर पर भी मुझे पहले से ही हेबी-जिम नहीं दिया गया, लेकिन यह सही लगता है।

उदाहरण ऐप में, मैं व्यूमोडेल के निर्माता में चयनित इटैम सेट कर रहा हूं। हालांकि, ऐप चलाने पर, कोई चयनित इटैम नहीं दिखाया जाता है। यहां तक ​​कि वीएस डिजाइनर भी "दूसरा विकल्प" दिखा रहा है!

चल रहा एप्लिकेशन: Running App वी.एस. डिजाइनर: Visual Studio Designer

जब SelectedItem सेटर डीबगिंग, आप कई गुजरता पर ध्यान देंगे। इसे ctor (1, नीचे डीबग लॉग देखें) में पहली बार "दूसरा विकल्प" सेट करने के बाद, यह शून्य (2) पर रीसेट हो जाएगा (बाहरी कोड से, मैं नियंत्रण में ही मानता हूं)। UI में ड्रॉपडाउन खोलते समय, इसे फिर से शून्य (3) पर सेट किया जाएगा, फिर मान को चुनते समय, इस मान से दो बार (4,5)। मैंने "दूसरा विकल्प" चुना, फिर "पहला विकल्प" (6-9) के साथ प्रक्रिया को दोहराया। यह निम्न लॉग (रिबन नियंत्रण ... से एक हजार और से एक बाध्यकारी अपवाद अनदेखी) का उत्पादन किया:

enter image description here

बड़ी समस्या स्पष्ट रूप से किया गया है (2) है, जो मेरी प्रारंभिक चयन को रीसेट कर रहा है। ऐसा लगता है कि नियंत्रण पहली बार कब दिखाया जाता है, यह रीसेट हो जाता है। एक टाइमर द्वारा मूल्य निर्धारित करने के लिए एक बहुत बदसूरत कामकाज होगा। इसे उपयोगकर्ता नियंत्रण की लोड की गई घटना में सेट करना मेरे लिए इस उदाहरण ऐप में काम करता है, लेकिन मेरे भारी वास्तविक जीवन ऐप में, यह नहीं करता है। वैसे भी, यह सब गलत लगता है। क्या कोई बेहतर समाधान जानता है?

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

उत्तर

5

जबकि देखें/UserControl से पहले ComboBox SelectedItem अपने आवेदन में शून्य पर रीसेट किया जाता है भरी हुई घटना उत्पन्न कर रहा है, ComboBox भरी हुई घटना वास्तव में दो बार निकाल दिया, दूसरी बार "देर से" पर्याप्त। तो मेरे वर्तमान समाधान है, जो मैं एक बेहतर एक के लिए खुशी-खुशी खाई, यह है:

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

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

तुम मुझे समय की भारी मात्रा को बचाया ...बहुत बहुत धन्यवाद !!! –

2

मैं सिर्फ मानक ComboBox का उपयोग कर समाप्त हो गया।

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

आप RibbonComboBox रूप में एक ही (बहुत समान) शैली चाहते हैं, का उपयोग

<ComboBox IsEditable="True" IsReadOnly="True" SelectedItem="{Binding Item}" ItemsSource="{Binding Items}"/> 
संबंधित मुद्दे