2013-10-27 9 views
9

मैं सी # और एमवीवीएम के लिए नया हूं, और मैंने SelectionChanged पर अपने व्यूमोडेल में ComboBox का मूल्य प्राप्त करने का प्रयास किया है। मैं संसाधनों के साथ या तो CallMethodAction या InvokeCommandAction का उपयोग कर यह पता लगा में कामयाब रहे:डब्ल्यूपीएफ - एमवीवीएम: चयन के बाद कॉम्बोबॉक्स मूल्य

  • System.Windows.Interactivity.dll
  • Microsoft.Expression.Interactions.dll

मेरे समस्या यह है कि इन दोनों तरीकों ComboBox का मूल्य वापस करने से पहले यह बदल गया है । क्या कोई परिवर्तन के बाद मूल्य प्राप्त करने के बारे में बता सकता है?

मैंने समाधान के लिए एसओ और Google के माध्यम से घंटों बिताए हैं, इसलिए मुझे आश्चर्य है कि अन्य भी हैं। किसी भी सलाह की सराहना की जाएगी!

मेरे कोड के नीचे है:

MainWindow.xaml

<Window x:Class="SelectionChange.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
     xmlns:si="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" 
     xmlns:vm="clr-namespace:SelectionChange" 
     Title="MainWindow" Width="300" Height="300"> 
    <Window.DataContext> 
     <vm:ViewModel /> 
    </Window.DataContext> 
    <Grid> 
     <ComboBox Name="SelectBox" VerticalAlignment="Top" SelectedIndex="0"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="SelectionChanged"> 
        <si:CallMethodAction MethodName="SelectionChanged" TargetObject="{Binding}" /> 
        <!--<i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=SelectBox, Path=Text}" />--> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
      <ComboBoxItem Content="Item 1" /> 
      <ComboBoxItem Content="Item 2" /> 
      <ComboBoxItem Content="Item 3" /> 
     </ComboBox> 
    </Grid> 
</Window> 

ViewModel.cs

namespace SelectionChange 
{ 
    using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 

    public class ViewModel 
    { 
     public ViewModel() 
     { 
      SelectionChangedCommand = new SelectionChangedCommand(); 
     } 

     public ICommand SelectionChangedCommand 
     { 
      get; 
      set; 
     } 

     public void SelectionChanged(object sender, EventArgs e) 
     { 
      ComboBox SelectBox = (ComboBox)sender; 
      MessageBox.Show("Called SelectionChanged: " + SelectBox.Text); 
     } 
    } 
} 

SelectionChangedCommand.cs

namespace SelectionChange 
{ 
    using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 

    public class SelectionChangedCommand : ICommand 
    { 
     public SelectionChangedCommand() 
     { 
     } 

     public event EventHandler CanExecuteChanged; 

     public bool CanExecute(object parameter) 
     { 
      return true; 
     } 

     public void Execute(object parameter) 
     { 
      MessageBox.Show("Executed SelectionChangedCommand: " + parameter); 
     } 
    } 
} 




संपादित करें: मेरे समाधान

यह पता चला मैं Binding काफी अच्छी तरह से और बदले में कुछ एक नहीं बल्कि जटिल तरीके से लागू करने के लिए सरल कोशिश कर रहा था समझ में नहीं आया! निर्भरताओं का उपयोग करने के बजाय, अब मैंने नियमित बाइंडिंग का उपयोग करके जो कुछ हासिल किया है, उसे हासिल कर लिया है। उदाहरण के तौर पर, मैंने TextBox को पर ComboBox से बाध्य किया है, जिसे INotifyPropertyChanged का उपयोग करके अद्यतन किया जाता है।

MainWindow.xaml Screenshot

MainWindow.xaml

<Window x:Class="SelectionChange.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:vm="clr-namespace:SelectionChange" 
     Title="MainWindow" Width="300" Height="300"> 
    <Window.DataContext> 
     <vm:ViewModel /> 
    </Window.DataContext> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 

     <ComboBox SelectedItem="{Binding SelectedItem}" SelectedIndex="0" Grid.Column="0" VerticalAlignment="Top"> 
      <ComboBoxItem Content="Item 1" /> 
      <ComboBoxItem Content="Item 2" /> 
      <ComboBoxItem Content="Item 3" /> 
     </ComboBox> 

     <!-- TextBox to display the ComboBox's SelectedIndex --> 
     <TextBox Text="{Binding SelectedIndex}" Grid.Column="1" VerticalAlignment="Top" /> 
    </Grid> 
</Window> 

ViewModel.cs

namespace SelectionChange 
{ 
    using System; 
    using System.ComponentModel; 
    using System.Windows.Controls; 

    public class ViewModel : INotifyPropertyChanged 
    { 
     public ViewModel() 
     { 
     } 

     // Property to store/retrieve ComboBox's SelectedIndex 
     private int _SelectedIndex; 
     public int SelectedIndex { get; set; } 

     // Property to bind to ComboBox's SelectedItem 
     private ComboBoxItem _SelectedItem; 
     public ComboBoxItem SelectedItem 
     { 
      get { return _SelectedItem; } 
      set 
      { 
       _SelectedItem = value; 

       // SelectedItem's Content 
       string Content = (string)value.Content; 

       // SelectedItem's parent (i.e. the ComboBox) 
       ComboBox SelectBox = (ComboBox)value.Parent; 

       // ComboBox's SelectedIndex 
       int Index = SelectBox.SelectedIndex; 

       // Store the SelectedIndex in the property 
       SelectedIndex = Index; 

       // Raise PropertyChanged with the name of the stored property 
       RaisePropertyChanged("SelectedIndex"); 
      } 
     } 

     // INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged; 
     private void RaisePropertyChanged(string PropertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(PropertyName)); 
     } 
    } 
} 
+0

सेट करते समय INotifyPropertyChanged इंटरफ़ेस को कार्यान्वित करना भी न भूलें, अगर मैं समझता हूं कि आप क्या करने का प्रयास कर रहे हैं, तो मुझे लगता है कि इससे http://stackoverflow.com/questions/4765362/mvvm-combobox बाध्यकारी – kenny

+0

मैं सिर्फ आपके लिए एक विचार छोड़ दूंगा। बाइडिंग मोड टूवे के साथ आपके व्यूमोडेल में किसी प्रॉपर्टी में चयनित इटम्स संपत्ति को बाध्य करने के बारे में कैसे? चयन परिवर्तन ईवेंट या कमांड बनाने की कोई ज़रूरत नहीं है। जब भी चयनित इटम्स मूल्य बदल जाता है तो आपको व्यूमोडेल में अपनी संपत्ति के सेटटर के अंदर अधिसूचित किया जाएगा। कोशिश करके देखो। –

+0

<कॉम्बोबॉक्स आइटमसोर्स = "{बाइंडिंग पथ = प्रॉपर्टीविच हैसलिस्ट, अपडेटसोर्स ट्रिगर = प्रॉपर्टी चेंज, मोड = टूवे}" चयनित इटैम = "{बाइंडिंग प्रॉपर्टीविचहाउस सिलेक्टेड इटिम}" । इस तरह कुछ कोशिश करो। – srsyogesh

उत्तर

19

यह आसान तरीका

<ComboBox MaxHeight="25" 
      ItemsSource="{Binding Source}" 
      SelectedItem="{Binding TheSelectedItem, Mode=TwoWay}" /> 

अपने ViewModel में कॉम्बो बॉक्स आइटम घोषित करने और एक संपत्ति "स्रोत" का उपयोग दृश्य में

List<string> _source = new List<string>{"Item 1", "Item 2", "Item 3"}; 
public List<string> Source 
{ 
    get { return _source; } 
} 

फिर वापस जाने के लिए करते हैं क्यों नहीं एक ऐसी संपत्ति को परिभाषित करें जिसमें चयनित आइटम

string _theSelectedItem = null; 
public string TheSelectedItem 
{ 
    get { return _theSelectedItem; } 
    set { _theSelectedItem = value; } // NotifyPropertyChanged 
} 

_source

+0

यह मेरे द्वारा समाप्त किए गए कार्यों के सबसे नज़दीक है, और मुझे लगता है कि आप कॉम्बोबॉक्स के साथ क्या करना चाहते थे, इस पर निर्भर करता है, समाधान (किसी और के लिए) हो सकता है। @ aks81, आपके उत्तर के लिए धन्यवाद! –

+0

आपका स्वागत है @AlistairTweed। – Sandesh

1

तुम सिर्फ चाहते हैं सूचना पाने के लिए अपने वर्तमान वस्तु परिवर्तन क्यों उपकरण का उपयोग नहीं जब ये सभी निर्भरताओं के बजाय पहले से ही WPF का हिस्सा हैं।

सबसे पहले अपने संग्रह में अंतर्निहित दृश्य प्राप्त करें और उस पर CurrentChanged ईवेंट का उपयोग करें।

ComboBoxList = new ObservableCollection<string>(); 
var view = CollectionViewSource.GetDefaultView(ComboBoxList); 
view.MoveCurrentTo(ComboBoxList[0]); 
view.CurrentChanged += new EventHandler(ComboBoxCurrentChanged); 

अपने XAML में आप सिर्फ अपने संग्रह को बाध्य करने और सच करने के लिए IsSynchronizedWithCurrentItem निर्धारित किया है।

<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ComboBoxList}"/> 
संबंधित मुद्दे