2014-04-19 6 views
5

के चयनित वैल्यू के आधार पर डब्ल्यूपीएफ एमवीवीएम कॉम्बोबॉक्स आइटमसोर्स सेट करने के सरल काम करने की आवश्यकता की आवश्यकता है क्या कोई मुझे कॉम्बोबॉक्स ए के चयनित इटैम के आधार पर कम्बोबॉक्स बी के आइटम्ससोर्स को सेट करने के लिए एक WPF MVVM एप्लिकेशन के लिए एक सरल कामकाजी उदाहरण दिखा सकता है?दूसरे कॉम्बोबॉक्स

ऐसा लगता है कि मुझे इस साइट पर जो मिला है, वह सब बहुत जटिल हो जाता है।

इसे करने के लिए "सही" एमवीवीएम तरीका क्या है?

धन्यवाद।

EDIT मैंने डिडिएर के उदाहरण का उपयोग करके अपडेट किया। मेरी XAML का एक उद्धरण:

<ComboBox Name="BrowserStackDesktopOS" ItemsSource="Binding Platforms.AvailableBrowserStackDesktopOSes}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopOSSelectedValue, Mode=TwoWay}"/> 

<ComboBox Name="BrowserStackDesktopOSVersion" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopOSVersions}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopOSVersionSelectedValue, Mode=TwoWay}"/> 

<ComboBox Name="BrowserStackDesktopBrowser" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopBrowsers}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopBrowserSelectedValue, Mode=TwoWay}"/> 

<ComboBox Name="BrowserStackDesktopBrowserVersion" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopBrowserVersions}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopBrowserVersionSelectedValue, Mode=TwoWay}"/> 

और पीछे मेरे कोड का एक उदाहरण:

public string BrowserStackDesktopOSSelectedValue { 
     get { return (string)GetValue(BrowserStackDesktopOSSelectedValueProperty); } 
     set { SetValue(BrowserStackDesktopOSSelectedValueProperty, value); 
       AvailableBrowserStackDesktopOSVersions = AvailableBrowserStackDesktopPlatforms.GetOSVersions(BrowserStackDesktopOSSelectedValue); 
       NotifyPropertyChanged("BrowserStackDesktopOSSelectedValue"); 
     } 
    } 

लेकिन जब मैं पहली बार ComboBox कुछ नहीं के लिए एक मूल्य का चयन होता है। मैं अगले कॉम्बोबॉक्स के आइटम्ससोर्स को पॉप्युलेट करके चाहता हूं।

मैंने क्या गलत किया है?

उत्तर

8

असल में आपको कॉम्बो बॉक्स विकल्पों के लिए मूल्यों के अपने एमवीवीएम 2 संग्रह और चयनित मूल्यों के लिए दो गुणों में बेनकाब करने की आवश्यकता है। शुरुआत में केवल पहले संग्रह में मूल्यों के साथ silled। जब पहला चयनित मूल्य बदलता है तो दूसरा संग्रह उपयुक्त मानों से भरा जा सकता है।

कोड के पीछे:

public partial class MainWindow : Window 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 

     //Set the data context of the window 
     DataContext = new TestVM(); 
    } 
} 


public class TestVM : INotifyPropertyChanged 
{ 

    #region Class attributes 

    protected static string[] firstComboValues = new string[] { "Choice_1", "Choice_2" }; 

    protected static string[][] secondComboValues = 
     new string[][] { 
       new string[] { "value_1_1", "value_1_2", "value_1_3" }, 
       new string[] { "value_2_1", "value_2_2", "value_2_3" } 
     }; 


    #endregion 

    #region Public Properties 

    #region FirstSelectedValue 

    protected string m_FirstSelectedValue; 

    /// <summary> 
    /// 
    /// </summary> 
    public string FirstSelectedValue 
    { 
     get { return m_FirstSelectedValue; } 
     set 
     { 
      if (m_FirstSelectedValue != value) 
      { 
       m_FirstSelectedValue = value; 
       UpdateSecondComboValues(); 
       NotifyPropertyChanged("FirstSelectedValue"); 
      } 
     } 
    } 

    #endregion 

    #region SecondSelectedValue 

    protected string m_SecondSelectedValue; 

    /// <summary> 
    /// 
    /// </summary> 
    public string SecondSelectedValue 
    { 
     get { return m_SecondSelectedValue; } 
     set 
     { 
      if (m_SecondSelectedValue != value) 
      { 
       m_SecondSelectedValue = value; 
       NotifyPropertyChanged("SecondSelectedValue"); 
      } 
     } 
    } 

    #endregion 

    #region FirstComboValues 

    protected ObservableCollection<string> m_FirstComboValues; 

    /// <summary> 
    /// 
    /// </summary> 
    public ObservableCollection<string> FirstComboValues 
    { 
     get { return m_FirstComboValues; } 
     set 
     { 
      if (m_FirstComboValues != value) 
      { 
       m_FirstComboValues = value; 
       NotifyPropertyChanged("FirstComboValues"); 
      } 
     } 
    } 

    #endregion 

    #region SecondComboValues 

    protected ObservableCollection<string> m_SecondComboValues; 

    /// <summary> 
    /// 
    /// </summary> 
    public ObservableCollection<string> SecondComboValues 
    { 
     get { return m_SecondComboValues; } 
     set 
     { 
      if (m_SecondComboValues != value) 
      { 
       m_SecondComboValues = value; 
       NotifyPropertyChanged("SecondComboValues"); 
      } 
     } 
    } 

    #endregion 

    #endregion 

    public TestVM() 
    { 
     FirstComboValues = new ObservableCollection<string>(firstComboValues); 
    } 

    /// <summary> 
    /// Update the collection of values for the second combo box 
    /// </summary> 
    protected void UpdateSecondComboValues() 
    { 
     int firstComboChoice; 
     for (firstComboChoice = 0; firstComboChoice < firstComboValues.Length; firstComboChoice++) 
     { 
      if (firstComboValues[firstComboChoice] == FirstSelectedValue) 
       break; 
     } 


     if (firstComboChoice == firstComboValues.Length)// just in case of a bug 
      SecondComboValues = null; 
     else 
      SecondComboValues = new ObservableCollection<string>(secondComboValues[firstComboChoice]); 

    } 


    #region INotifyPropertyChanged implementation 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void NotifyPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion 
} 

और जुड़े XAML

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Name="window" x:Class="Testing1.MainWindow"> 

    <Grid> 

     <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width=" 300"> 
      <Grid.RowDefinitions> 
       <RowDefinition/> 
       <RowDefinition Height="10"/> 
       <RowDefinition/> 
      </Grid.RowDefinitions> 

      <ComboBox x:Name="FirstOne" ItemsSource="{Binding FirstComboValues}" SelectedItem="{Binding FirstSelectedValue, Mode=TwoWay}"/> 

      <ComboBox x:Name="SecondOne" ItemsSource="{Binding SecondComboValues}" SelectedItem="{Binding SecondSelectedValue, Mode=TwoWay}" Grid.Row="2"/> 

     </Grid> 

    </Grid> 

</Window> 

आप कॉम्बो बक्से के SelectedValue गुण देख सकते हैं TwoWay मोड में आबद्ध कर रहे हैं ताकि जब SelectedValue यहाँ कार्यान्वयन का एक उदाहरण है कॉम्बो बॉक्स की संपत्ति में परिवर्तन यह वीएम पक्ष पर मूल्य बदलता है। और FirstSelectedValue में संपत्ति सेटर UpdateSecondComboValues() विधि को दूसरे कॉम्बो बॉक्स के मानों को अपडेट करने के लिए कहा जाता है।

संपादित करें:

यह होता है क्योंकि आप दोनों INotifPropertyChanged और DependencyObject मिलाया। आपको उनमें से एक चुनना चाहिए। आम तौर पर आप अपने वीएम में बदलकर INotifyProperty को लागू करते हैं और प्रॉपर्टी सेटर में कोड काम करेगा।

यदि आप निर्भरता ऑब्जेक्ट से प्राप्त करते हैं, तो आपको सेटटर/गेटर में कोई कोड नहीं लिखना चाहिए। इसे दोवे बाध्यकारी द्वारा कभी नहीं बुलाया जाएगा। यह केवल GetValue (...) को आंतरिक रूप से कॉल करेगा। निष्पादित करने के लिए DependencyProperty पर कोई क्रिया को बदलने आप एक संपत्ति बदली हुई हैंडलर के साथ अलग ढंग से यह घोषणा करनी चाहिए सक्षम होने के लिए:

#region BrowserStackDesktopOSSelectedValue 

/// <summary> 
/// BrowserStackDesktopOSSelectedValue Dependency Property 
/// </summary> 
public static readonly DependencyProperty BrowserStackDesktopOSSelectedValue Property = 
    DependencyProperty.Register("BrowserStackDesktopOSSelectedValue ", typeof(string), typeof(YourVM), 
     new FrameworkPropertyMetadata((string)null, 
      new PropertyChangedCallback(OnBrowserStackDesktopOSSelectedValue Changed))); 

/// <summary> 
/// Gets or sets the BrowserStackDesktopOSSelectedValue property. This dependency property 
/// indicates .... 
/// </summary> 
public string BrowserStackDesktopOSSelectedValue 
{ 
    get { return (string)GetValue(BrowserStackDesktopOSSelectedValue Property); } 
    set { SetValue(BrowserStackDesktopOSSelectedValue Property, value); } 
} 

/// <summary> 
/// Handles changes to the BrowserStackDesktopOSSelectedValue property. 
/// </summary> 
private static void OnBrowserStackDesktopOSSelectedValue Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    YourVM target = (YourVM)d; 
    string oldBrowserStackDesktopOSSelectedValue = (string)e.OldValue; 
    string newBrowserStackDesktopOSSelectedValue = target.BrowserStackDesktopOSSelectedValue ; 
    target.OnBrowserStackDesktopOSSelectedValue Changed(oldBrowserStackDesktopOSSelectedValue , newBrowserStackDesktopOSSelectedValue); 
} 

/// <summary> 
/// Provides derived classes an opportunity to handle changes to the BrowserStackDesktopOSSelectedValue property. 
/// </summary> 
protected virtual void OnBrowserStackDesktopOSSelectedValue Changed(string oldBrowserStackDesktopOSSelectedValue , string newBrowserStackDesktopOSSelectedValue) 
{ 
    //Here write some code to update your second ComboBox content. 
    AvailableBrowserStackDesktopOSVersions = AvailableBrowserStackDesktopPlatforms.GetOSVersions(BrowserStackDesktopOSSelectedValue); 
} 

#endregion 

तरह से मैं हमेशा Dr WPF snippets का उपयोग ड्राफ्ट पैरा लिखने के लिए तो यह बहुत तेजी से चला जाता है के द्वारा।

+0

धन्यवाद डिडिएर, ऊपर अपना ईडीआईटी देखें। –

+0

ठीक है मैंने अपना जवाब संपादित कर लिया है। – Dmitry

+0

धन्यवाद Didier, यह काम किया है। –

संबंधित मुद्दे