2013-03-06 4 views
7

का उल्लंघन किए बिना डब्ल्यूपीएफ में टैबकंट्रोल से टैब को कैसे बदलें मेरे डब्ल्यूपीएफ विंडोज में एक टैबकंट्रोल है जो विभिन्न टैब पर सामग्री प्रदर्शित करता है। नीचे दिए गए बटन पर एक क्लिक आईसीओएमएंड इंटरफ़ेस/बाध्यकारी के माध्यम से एक विधि निष्पादित करता है। बुलाया गया विधि टेक्स्ट उत्पन्न करता है जिसका उद्देश्य दूसरे टैब में प्रदर्शित करना है।एमवीवीएम पैटर्न

Application Mockup

मैं कैसे MVVM पैटर्न का उल्लंघन किए बिना बटन पर क्लिक दूसरे टैब में स्विच कर सकते हैं?

मैंने TabItem को बांधने की कोशिश की। मेरे दृश्य मॉडल में कुछ चुनिंदा संपत्ति है लेकिन मैं अन्य टैब (टैब 1) का भी उपयोग करना चाहता था।

किसी भी विचार?

+4

कृपया एक WPF 'विंडो' को" फ़ॉर्म "न कहें। यह अपमान है। –

+0

लॉल @ हाईकोर - मैंने सचमुच कुछ दिनों पहले एक सहयोगी को एक ही चीज़ कहा था ... – JerKimball

+3

कृपया देखें [यह] (http://stackoverflow.com/questions/15209870/dynamically-updating-tabcontrol-content- एटी-रनटाइम/15210593 # 15210593) एक एमवीवीएम दृष्टिकोण से, 'टैबकंट्रोल' क्या है और इसका इलाज कैसे किया जाना चाहिए इसका स्पष्टीकरण। –

उत्तर

11

मैंने इसे अपने आप से बाहर पाया।

कुंजी दो तरह से बाध्यकारी है। जब बटन क्लिक किया जाता है तो यह संपत्ति DisplayXamlTab सत्य सेट करता है। IsSelected विशेषता इस चर के लिए बाध्य है। यदि कोई अन्य टैब क्लिक किया गया है तो बाध्यकारी DisplayXamlTab प्रॉपर्टी को गलत पर सेट करेगा।

नोट: UpdateSourceTrigger=PropertyChanged भी बहुत महत्वपूर्ण

कोड नीचे आता है:

XAML:

 <TabItem Header="XAML" IsSelected="{Binding DisplayXamlTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
      <Grid Background="#FFE5E5E5"> 
       <TextBox x:Name="TxtXamlOutput" IsReadOnly="True" Text="{Binding XamlText, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/> 
      </Grid> 
     </TabItem> 

सी # संपत्ति:

private bool displayXamlTab; 
public bool DisplayXamlTab 
{ 
    get { return this.displayXamlTab; } 
    set 
    { 
     this.displayXamlTab = value; 
     this.RaisePropertyChanged("DisplayXamlTab"); 
    } 
} 
+0

आप RaisePropertyChanged कैसे प्राप्त कर रहे हैं? –

+0

RaisePropertyChanged INotifyPropertyChanged इंटरफ़ेस का एमवीवीएमलाइट कार्यान्वयन है। – Joel

+0

ओह, मैं इसके बारे में सोच रहा था - thx –

0

आप कुछ प्रकार के "नेविगेशन" संदेश प्रसारित करने के लिए कुछ प्रकार के "Event Aggregator" पैटर्न (आईई Messenger कक्षा एमवीवीएम लाइट) का उपयोग करना चाहेंगे। आपका दृश्य - टैबकंट्रोल - विशिष्ट संदेश के लिए सुन सकता है, और संदेश प्राप्त होने पर टैब 2 पर नेविगेट कर सकता है।

वैकल्पिक रूप से, आप अपने व्यूमोडेल में टैबकंट्रोल की "SelectedItem" संपत्ति को बाध्य कर सकते हैं, और बस अपने वीएम के भीतर से CurrentTab = MySecondTabViewModel पर कॉल कर सकते हैं। ओपी को टिप्पणियों में @HighPoint द्वारा अनुशंसित approach है, लेकिन मैं प्रशंसक नहीं हूं; निचे देखो। इस दृष्टिकोण के लिए एक और चेतावनी है कि आप, DataTemplates से परिचित होना के रूप में आप प्रत्येक ViewModel जो आप प्रदर्शित करने के लिए एक दृश्य के मैप करने के लिए की आवश्यकता होगी की जरूरत है।

मैं व्यक्तिगत रूप से पहले दृष्टिकोण की तरह, क्योंकि मैं इसे नहीं मानते एक टैब नेविगेशन को संभालने के लिए ViewModel की "जिम्मेदारी" किया जाना है। यदि आप अपने व्यूमोडेल में डेटा बदलते समय बस अपना दृश्य अलर्ट करते हैं, तो आप यह देखने के लिए दृश्य को अनुमति देते हैं कि वह टैब बदलना चाहेगा या नहीं।

+0

यह आवश्यक नहीं है और अनियंत्रित ओवरहेड जोड़ता है और रखरखाव को कम करता है। कृपया मेरी टिप्पणी में लिंक देखें। –

+0

@HighCore - ऊपर मेरी टिप्पणियां देखें। मैं "चयनित इटैम" बाध्यकारी का उपयोग करने का प्रशंसक नहीं हूं। – BTownTKD

+0

मैं असहमत हूं। लेकिन आपके पास एक वैध बिंदु है। एक तरफ के रूप में, किसी भी WPF डेवलपर के लिए डेटा टेम्पलेट्स जरूरी है। दूसरे से, अधिक अमूर्त दृष्टिकोण, आप सोच सकते हैं कि "सक्रिय विजेट" सेटिंग वास्तव में वीएम की ज़िम्मेदारी है। –

1

आप दृश्य मॉडल और TabControl.SelectedIndex संपत्ति के बीच एक बाध्यकारी बना सकते हैं - यानी, 0 पहले TabItem चयन करता है, 1 का चयन करता है दूसरा, आदि

<TabControl DataContext="..." SelectedIndex="{Binding SomeVmProperty}" ... 

(वैकल्पिक रूप से, पर निर्भर करता है कि कैसे आप मिल गया है चीजों की स्थापना की है, तो आप SelectedItem के खिलाफ बाँध सकता है ...)

+2

यह मेरे लिए क्यों काम नहीं कर रहा है? संपत्ति परिवर्तन, नोटिफ़िस, लेकिन यूआई कभी भी टैब को बदलता नहीं है। –

12

यदि आप जा रहे हैं MVVM जिस तरह से आप के पीछे कोड में दो निर्भरता गुण पैदा करने के लिए जा रहे हैं:

  • ObservableCollection<ItemType> Items;
  • ItemType MySelectedItem;

फिर, आइटम को TabControl ItemsSource संपत्ति बाँध और MySelectedItem

<TabControl ItemsSource="{Binding Items}" 
     SelectedItem="{Binding MySelectedItem, Mode=TwoWay}"> 
<TabControl.ItemTemplate> 
    <DataTemplate> 
     <... here goes the UI to display ItemType ... > 
    </DataTemplate> 
    </TabControl.ItemTemplate> 
</TabControl> 

को SelectedItem संपत्ति बाँध आपके द्वारा चयनित टैब बदलने के लिए चाहते हैं, तो बस MySelectedItem निर्भरता संपत्ति को अद्यतन

2

हालांकि इस सवाल का काफी पुराना है और अच्छी तरह से पहले से ही जवाब दिया, मैंने सोचा कि मैं यह अतिरिक्त जवाब जोड़ूंगा में चयनित TabItem को बदलने का एक वैकल्पिक तरीका प्रदर्शित करने के लिए। यदि आपके पास प्रत्येक TabItem के लिए एक दृश्य मॉडल है, तो यह निर्धारित करने के लिए कि क्या यह चुना गया है या नहीं, IsSelected संपत्ति होने में यह सहायक हो सकता है। यह संभव है डेटा ItemContainerStyle संपत्ति का उपयोग कर TabItem.IsSelected संपत्ति के साथ इस IsSelected संपत्ति बाध्य करने के लिए:

<TabControl ItemsSource="{Binding MenuItems}" TabStripPlacement="Top"> 
    <TabControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type ControlViewModels:MenuItemViewModel}"> 
      <StackPanel Orientation="Horizontal"> 
       <Image Source="{Binding ImageSource}" Margin="0,0,10,0" /> 
       <TextBlock Text="{Binding HeaderText}" FontSize="16" /> 
      </StackPanel> 
     </DataTemplate> 
    </TabControl.ItemTemplate> 
    <TabControl.ContentTemplate> 
     <DataTemplate DataType="{x:Type ControlViewModels:MenuItemViewModel}"> 
      <ContentControl Content="{Binding ViewModel}" /> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
    <TabControl.ItemContainerStyle> 
     <Style TargetType="{x:Type TabItem}"> 
      <Setter Property="IsSelected" Value="{Binding IsSelected}" /> 
     </Style> 
    </TabControl.ItemContainerStyle> 
</TabControl> 

अब आप चयनित TabItem इस तरह जनक दृश्य मॉडल से बदल सकते हैं:

MenuItems[0].IsSelected = true; 

ध्यान दें कि क्योंकि यह गुण TabItem.IsSelected संपत्ति से जुड़ा हुआ डेटा है, इसे कॉल कर रहा है ...:

MenuItems[1].IsSelected = true; 

... वास्तव में MenuItems[0].IsSelected संपत्ति false पर स्वचालित रूप से सेट भी करेगा। इसलिए यदि आपके द्वारा काम कर रहे दृश्य मॉडल में IsSelected संपत्ति सत्य पर सेट है, तो आप सुनिश्चित हो सकते हैं कि इसका संबंधित दृश्य TabControl में चुना गया है।

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