2014-04-01 6 views
40

का उपयोग करके विचारों के माध्यम से नेविगेट करें मैं एमवीवीएम पैटर्न का उपयोग कर अपना पहला WPF बना रहा हूं। इस समुदाय की मदद से, मैं अपना मॉडल, मेरा पहला व्यू मॉडेल बनाने और देखने का प्रबंधन करता हूं। अब मैं मूल एप्लिकेशन लेआउट इंटरफेस को डिजाइन करने वाले ऐप में कुछ जटिलता जोड़ना चाहता हूं।डब्ल्यूपीएफ एमवीवीएम पैटर्न

  • Main.XAML
  • Products.XAML
  • Clients.XAML

मुख्य एक मेनू और एक अंतरिक्ष बच्चे दृश्य (उत्पाद और ग्राहक) को लोड करना होगा: मेरा विचार कम से कम 2 बच्चे विचारों और एक मुख्य दृश्य है और कई XAML पर उन्हें अलग करने के लिए है। अब एमवीवीएम पैटर्न के बाद विचारों के बीच सभी नेविगेशन तर्क को व्यूमोडेल पर लिखा जाना चाहिए।

  • MainViewModel
  • ProductsViewModel
  • ClientsViewModel
  • NavigationViewModel

तो NavigationViewModel बच्चे ViewModels का एक संग्रह को शामिल करना चाहिए: तो मील विचार 4 ViewModels है? और एक सक्रिय व्यूमॉडल सही है?

तो मेरी प्रश्न हैं:

1) मैं अलग-अलग दृश्यों (उत्पाद, ग्राहक) MVVM पद्धति का उपयोग कर मुख्य दृश्य पर लोड कर सकते हैं कैसे?

2) मैं नेविगेशन व्यू मॉडल को कैसे कार्यान्वित करूं?

3) मैं खुले या सक्रिय विचारों की अधिकतम संख्या को कैसे नियंत्रित कर सकता हूं?

4) मैं खुले विचारों के बीच कैसे स्विच कर सकता हूं?

मैं बहुत सारी खोज और पढ़ रहा हूं और WPF के साथ एमवीवीएम नेविगेशन का कोई आसान कामकाजी उदाहरण नहीं मिला जो मुख्य दृश्य के अंदर कई दृश्य लोड करता है। तब से कई:

1) बाहरी टूलकिट का उपयोग करें, जिसे मैं अभी उपयोग नहीं करना चाहता हूं।

2) एक ही एक्सएएमएल फ़ाइल में सभी विचारों को बनाने के लिए सभी कोड डालें, जो एक अच्छा विचार नहीं लगता है क्योंकि मुझे 80 विचारों को लागू करने की आवश्यकता है!

मैं यहां सही रास्ते में हूं? किसी भी मदद, विशेष रूप से कुछ कोड के साथ सराहना की जाएगी।

अद्यतन

तो, मैं एक परीक्षण परियोजना @LordTakkera सलाह निम्नलिखित बनाते हैं लेकिन अटक जाते हैं। Solution

मैं बनाने के लिए::

  • Two Models (Clients and Products)

  • One MainWindow and two wpf user controls(Clients and Products) XAML.

  • Three ViewModels (Clients, Products and Main ViewModel)

तब मैं इसी ViewModel करने के लिए प्रत्येक दृश्य पर DataContext सेट यह कैसे मेरे समाधान लग रहा है की तरह है। इसके बाद मैं इस तरह सामग्री प्रदाता के साथ मेनविंडो बना देता हूं और इसे व्यूमोडेल की संपत्ति से जोड़ता हूं।

MainWindow.XAML

<Window x:Class="PruevaMVVMNavNew.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="519" Width="890">  
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="150"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="80"/> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="20"/> 
    </Grid.RowDefinitions>   
    <Border Grid.Column="0" Grid.ColumnSpan="2" Background="AntiqueWhite" ></Border> 
    <Border Grid.Row="1" Grid.RowSpan="2" Background="AliceBlue"></Border> 
    <Border Grid.Row="1" Grid.Column="1" Background="CadetBlue"></Border>     
    <ContentPresenter Grid.Row="1" Grid.Column="1" x:Name="ContentArea" Content="{Binding CurrentView}"/>   
    <StackPanel Margin="5" Grid.Column="0" Grid.Row="1">    
     <Button>Clients</Button> 
     <Button>Products</Button> 
    </StackPanel> 
</Grid> 

और यह भी इस MainWindow से viewmodel है:

class Main_ViewModel : BaseViewModel 
    { 
     public Main_ViewModel() 
     { 
      CurrentView = new Clients(); 
     } 

     private UserControl _currentView; 
     public UserControl CurrentView 
     { 
      get 
      { 
       return _currentView; 
      } 
      set 
      { 
       if (value != _currentView) 
       { 
        _currentView = value; 
        OnPropertyChanged("CurrentView"); 
       } 
      } 
     } 

    } 

तो डिफ़ॉल्ट ग्राहकों द्वारा इस भार को देखने और इस तरह दिखता है (जो सिर्फ है सही!):

Current state

तो मैं मैं कोई तरीका होना चाहिए बटन मुख्य ViewModel की CurrentView संपत्ति के साथ एक निश्चित viemodel साथ, बाईं तरफ संबंधित और उसके बाद के लिए बाध्य करने के लिए उन्हें लगता है। मैं उसे कैसे कर सकता हूँ?

UPDATE2

@LordTakkera सलाह मैं अपने मुख्य ViewModel इस तरह से संशोधित के अनुसार:

class Main_ViewModel : BaseViewModel 
    { 
     public ICommand SwitchViewsCommand { get; private set; } 

     public Main_ViewModel() 
     { 
      //CurrentView = new Clients(); 
      SwitchViewsCommand = new RelayCommand((parameter) => CurrentView = (UserControl)Activator.CreateInstance(parameter as Type)); 
     } 

     private UserControl _currentView; 
     public UserControl CurrentView 
     { 
      get 
      { 
       return _currentView; 
      } 
      set 
      { 
       if (value != _currentView) 
       { 
        _currentView = value; 
        OnPropertyChanged("CurrentView"); 
       } 
      } 
     } 
    } 

मैं DelegateCommand के बजाय RelayCommand का उपयोग लेकिन मैं इसे उसी तरह काम करता है। आदेश निष्पादित किया जाता है जब मैं बटन और प्रकार पैरामीटर स्ट्रिंग ठीक मारा, लेकिन मैं इस त्रुटि मिलती है:

Error

अनुवाद: मूल्य खाली नहीं रह सकती। पैरामीटर नाम: प्रकार। सुझाव वस्तु उदाहरण बनाने के लिए नया कीवर्ड का उपयोग करें, मुझे नहीं पता कि नया कीवर्ड कहां रखा जाए। मैंने कमांड पैरामीटर पर कोशिश की है लेकिन यह काम नहीं करेगा। कोई उपाय? धन्यवाद

अद्यतन 3

सभी सलाह के बाद और यहाँ प्राप्त करने में मदद, और बहुत काम है, यहाँ मेरा अंतिम नेविगेशन मेनू और अपने आवेदन इंटरफेस के लिए आधार है।

Capture 1 Capture 2

+1

अच्छा अनुप्रयोग Eric.I wpf.I के लिए नया करने के लिए तुम pls पोस्ट code.It अधिक ज्ञान प्राप्त करने के लिए बहुत मददगार होगा एक ही layout.Could साथ आवेदन डिजाइन करने के लिए संघर्ष कर रहा हूँ। – Oasis

उत्तर

19

मुझे यकीन है कि आप एक अलग "नेविगेशन" दृश्य मॉडल की जरूरत है नहीं कर रहा हूँ, आप आसानी से मुख्य में डाल सकता है। किसी भी तरह से:

अपने "बच्चा" विचारों को अलग करने के लिए, मैं अपने "मुख्य" दृश्य पर एक साधारण ContentPresenter का प्रयोग करेंगे:

<ContentPresenter Content="{Binding CurrentView}"/> 

सबसे आसान समर्थन संपत्ति को लागू करने की जिस तरह से यह एक UserControl बनाने के लिए है, हालांकि कुछ लोग तर्क देंगे कि ऐसा करने से एमवीवीएम का उल्लंघन होता है (क्योंकि व्यूमोडेल अब "व्यू" क्लास पर निर्भर है)। आप इसे एक वस्तु बना सकते हैं, लेकिन आप कुछ प्रकार की सुरक्षा खो देते हैं। इस मामले में प्रत्येक दृश्य UserControl होगा।

उनके बीच स्विच करने के लिए, आपको कुछ प्रकार के चयन नियंत्रण की आवश्यकता होगी। मैंने पहले रेडियो बटन के साथ इस किया है, तो आप उन्हें तो जैसे बाँध:

<RadioButton Content="View 1" IsChecked="{Binding Path=CurrentView, Converter={StaticResource InstanceEqualsConverter}, ConverterParameter={x:Type views:View1}"/> 

कनवर्टर "कन्वर्ट" यदि वर्तमान नियंत्रण पैरामीटर का एक प्रकार है कि यह सिर्फ जाँच करता है में बहुत सरल है, "ConvertBack में, "यह पैरामीटर का एक नया उदाहरण देता है।

public class InstanceEqualsConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (parameter as Type).IsInstanceOfType(value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (bool)value ? Activator.CreateInstance(parameter as Type) : Binding.DoNothing; 
    } 
} 

एक combobox या अन्य चयन नियंत्रण करने के लिए बाइंडिंग समान प्रतिमान का अनुसरण करेंगे।

बेशक आप डेटाटेम्प्लेट्स (एक चयनकर्ता के साथ, दुर्भाग्य से कुछ ऐसा नहीं किया है जो मैंने पहले किया है) का उपयोग कर सकते हैं और उन्हें मर्ज किए गए शब्दकोशों (अलग XAML की अनुमति देकर) का उपयोग करके अपने संसाधनों में लोड कर सकते हैं। मैं व्यक्तिगत रूप से उपयोगकर्ता नियंत्रण मार्ग पसंद करता हूं, जो आपके लिए सबसे अच्छा है चुनें!

यह दृष्टिकोण "एक समय में एक दृश्य" है।यह कई विचारों में कनवर्ट करना अपेक्षाकृत आसान होगा (आपका उपयोगकर्ता नियंत्रण उपयोगकर्ता नियंत्रण का संग्रह बन जाता है, उपयोग करें। कनवर्टर आदि में शामिल है)।

बटन के साथ ऐसा करने के लिए, मैं आदेशों का उपयोग और CommandParameter का लाभ ले जाएगा।

बटन XAML दिखाई देगा:

<Button ... Command={Binding SwitchViewsCommand} CommandParameter={x:Type local:ClientsView}/> 

तो फिर तुम एक प्रतिनिधि के आदेश है (ट्यूटोरियल here) कि कनवर्टर से उत्प्रेरक कोड चलाता है:

public ICommand SwitchViewsCommand {get; private set;} 

public MainViewModel() 
{ 
    SwitchViewsCommand = new DelegateCommand((parameter) => CurrentView = Activator.CreateInstance(parameter as Type)); 
} 

कि के ऊपर से है मेरा सिर, लेकिन बहुत करीब होना चाहिए। मुझे बताएं कि यह कैसे जाता है!

मुझे पता है कि अगर मैं कोई और जानकारी देने करते हैं!

अद्यतन:

अपनी चिंताओं का जवाब करने के लिए:

  1. हाँ, हर बार जब आप बटन को देखने का एक नया उदाहरण बनाई गई है धक्का। आप आसानी से Dictionary<Type, UserControl> रख कर इसे ठीक कर सकते हैं जिसमें पूर्व-निर्मित दृश्य और अनुक्रमणिका शामिल है। उस मामले के लिए, आप Dictonary<String, UserControl> का उपयोग कर सकते हैं और कनवर्टर पैरामीटर के रूप में सरल स्ट्रिंग का उपयोग कर सकते हैं। नुकसान यह है कि आपका व्यूमोडेल उन प्रकार के विचारों के साथ कसकर मिल जाता है जो इसे पेश कर सकते हैं (क्योंकि इसे शब्दकोश कहा जाता है)।

  2. वर्ग निपटाए मिलना चाहिए, जब तक कि कोई और इसे करने के लिए एक संदर्भ रखती है (लगता ईवेंट हैंडलर्स कि इसके लिए पंजीकृत)।

  3. आप बाहर बिंदु के रूप में, केवल एक ही दृश्य एक समय में बनाया ताकि आप स्मृति के बारे में चिंता करने की जरूरत नहीं होनी चाहिए है। आप निश्चित रूप से एक कन्स्ट्रक्टर को बुला रहे हैं, लेकिन यह महंगा नहीं है, खासकर आधुनिक कंप्यूटरों पर जहां हमारे पास अतिरिक्त CPU समय शेष है। हमेशा के रूप में, प्रदर्शन प्रश्नों का उत्तर "इसे बेंचमार्क" है क्योंकि केवल आपके पास वास्तव में सर्वोत्तम प्रदर्शन करने के लिए इच्छित तैनाती लक्ष्य और संपूर्ण स्रोत तक पहुंच है।

+0

धन्यवाद! मैं आपके द्वारा पोस्ट की गई सभी चीज़ों को काफी समझ नहीं पा रहा हूं, लेकिन मैं मूलभूत सामग्री को मूल सामग्री सामग्री (किसी प्रकार का खाली बॉक्स) पर रखना चाहता हूं, जहां मैं सक्रिय दृश्य के लिए बाहरी XAML लोड कर सकता हूं। मैं इस विचार के साथ बहुत ही सरल नमूना कोड बनाने की कोशिश करूंगा और प्रश्न अपडेट करूँगा ताकि आप मेरी मदद कर सकें। फिर से धन्यवाद! – ericpap

+0

क्या आप मेरे अपडेट की समीक्षा कर सकते हैं? धन्यवाद! – ericpap

+0

अच्छा लग रहा है! अगर मेरा कमांड उदाहरण मदद करता है तो मुझे बताएं। – BradleyDotNET

0

IMHO सबसे अच्छा आप के लिए चुनें MVVM फ्रेमवर्क (प्रिज्म, MMVM लाइट, खटमल, आदि) का उपयोग करने के क्योंकि नेविगेशन पहले से ही लागू किया गया है है। यदि आप अपना खुद का नेविगेशन बनाना चाहते हैं - डेटा टेम्पलेट का प्रयास करें।

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