2011-10-24 24 views
12

मैं कैलिबर्न का उपयोग करके सीखने की कोशिश कर रहा हूं। डब्ल्यूपीएफ के साथ माइक्रो। मैं दृश्य के अंदर कई विचार कैसे जोड़ सकता हूं?WPF और Caliburn का उपयोग करके दृश्य के अंदर कई दृश्य जोड़ें। माइक्रो

<Window x:Class="ProjectName.Views.MainView" 
     ...> 
<Grid> 
     <views:MyControlView /> 
</Grid> 
</Window> 

एक अन्य दृश्य, viewmodel साथ: MyControlViewModel

<UserControl x:Class="ProjectName.Views.MyControlView" 
     ...> 
<Grid> 
    ... 
</Grid> 
</UserControl> 

मैं सिर्फ दृश्य जोड़ते हैं, तो यह पता नहीं लगा होगा कि यह उपयुक्त नाम के साथ एक viewmodel है। मैं इसे कैसे बांध सकता हूं?

मैंने विभिन्न बूटस्ट्रैपर्स के साथ प्रयास किया है और कैल जैसे कुछ का उपयोग किया है: Bind.Model = "पथ/वर्गनाम/दोनों का विलय"। इसे मुख्यदृश्य और उपयोगकर्ता नियंत्रण (MyControlView) में जोड़ने का प्रयास किया है। मैं इस मामले के बारे में किसी भी मदद के लिए बहुत आभारी हूं। मैं बहुत ज्यादा अटक कर रहा हूँ, और मैं वास्तव में Caliburn.Micro :)

शुभकामनाओं सहित, diamondfish

संपादित उपयोग करना चाहते हैं: मैं अभी भी यह काम करने के लिए नहीं मिल सकता है, समस्या में हो रहा है बूटस्ट्रैपर या कुछ और। लेकिन सिर्फ स्पष्टीकरण के लिए, यह मेरा कोड है जो मैं टेस्टप्रोजेक्ट के लिए दौड़ रहा हूं।

MainView XAML:

<Window x:Class="Test.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro" 
    xmlns:views="clr-namespace:Test.Views" 
    Title="MainWindow" Height="360" Width="640"> 
<Grid> 
    <views:MyControlView /> 
</Grid> 

MainViewModel कोड:

public partial class MainViewModel : PropertyChangedBase 
{ 
} 

MyControlView XAML:

<UserControl x:Class="Test.Views.MyControlView" 
     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:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro" 
     cal:Bind.Model="Test.MyControlViewModel" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<Grid> 
    <TextBlock Text="{Binding MyProp}"/> 
</Grid> 

MyControlView कोड:

public class MyControlViewModel : PropertyChangedBase 
{ 
    public string MyProp 
    { 
     get { return "Working"; } 
    } 
} 

त्रुटि का स्क्रीनशॉट: http://clip2net.com/s/1gtgt

मैं

cal:Bind.Model="Test.ViewModels.MyControlViewModel" 

रूप में अच्छी तरह की कोशिश की है।

xmlns:cal="http://www.caliburnproject.org" 

अपने प्रोजेक्ट http://clip2net.com/s/1gthM

प्रलेखन के बाद का स्क्रीनशॉट ज्यादातर Silverlight के लिए है और कभी कभी Caliburn और नहीं मुख्यमंत्री के लिए, मैं bootstrapper गलत लागू किया है हो सकता है: इसके अलावा कैलोरी-संदर्भ की कोशिश की। इस परीक्षण-परियोजना के लिए, यह सिर्फ इस तरह है: (App.xaml में .xaml-परिवर्तन के साथ)

public class BootStrapper : Bootstrapper<MainViewModel> 
{ 
} 

कृपया मुझे यहाँ मदद बाहर! ऐसा लगता है यह कुछ बुनियादी सामान मैं याद कर रहा हूँ :) है की तरह

+0

जोड़ने - एमवीवीएम टैग को शामिल करने के लिए संपादित पोस्ट, एसओ में आपका स्वागत है! – EtherDragon

+0

उत्तरदाता की जांच करें - मैंने प्रकार को निर्यात करने के बारे में एक अनुभाग जोड़ा। दृश्य से संबंधित ViewModel को खोजने के लिए c.m के लिए यह एक महत्वपूर्ण आवश्यकता है। – EtherDragon

उत्तर

16

संपादित करें - नई (और अधिक पूर्ण) नीचे उत्तर:

ठीक है, आप के लिए मुख्यमंत्री सामान का एक बहुत कर रहा है, यह सब अपनी कक्षाओं करने के बारे में है और सीएम के लिए तैयार होने के लिए तैयार xaml। जैसा ऊपर बताया गया है, मैं फ्रेमवर्क द्वारा अंतर्निहित कोड धारणाओं पर भरोसा करने के बजाय स्पष्ट कोड लिखना पसंद करता हूं।

तो, डिफ़ॉल्ट सीएम प्रोजेक्ट से बूटस्ट्रैपर ठीक है।

public class AppBootstrapper : Bootstrapper<MainViewModel> 
{ 
    // ... You shouldn't need to change much, if anything 
} 

खंड `Bootstrapper 'बहुत महत्वपूर्ण है, यह इंगित करता है जो ViewModel अपने पहले, या मुख्य स्क्रीन है, जब एप्लिकेशन को शुरू होता है।

[Export(Typeof(MainViewModel))] 
public class MainViewModel : Screen, IShell 
{ 
    [ImportingConstructor] 
    public MainViewModel(YourFirstViewModel firstViewModel, YourSecondViewModel secondviewModel) // etc, for each child ViewModel 
    { 
    } 
} 

में [ImportingConstructor] आप से यह दर्शाते हैं कि MainViewModel अन्य ViewModels की उपस्थिति की आवश्यकता है अन्य कुछ भी करने की जरूरत नहीं है। मेरे विशेष मामले में, मुझे अपने मेनव्यू मॉडेल को एक कंटेनर और केवल कंटेनर होना पसंद है, इवेंट लॉजिक कहीं और संभाला जाता है। लेकिन आप यहां आसानी से अपने हैंडल तर्क को आसानी से प्राप्त कर सकते हैं - लेकिन यह थोड़ी देर की अन्य चर्चा है।

अब प्रत्येक बच्चे को मॉडल को खुद को निर्यात करने की आवश्यकता है इसलिए सीएम जानता है कि उन्हें कहां मिलना है।

[Export(Typeof(YourFirstViewModel))] 
public class YourFirstViewModel : IShell 
{ 
    // VM properties and events here 
} 

यदि आप केवल डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग कर रहे हैं तो एक आयातक कन्स्ट्रक्टर निर्दिष्ट करने की आवश्यकता नहीं है।

अब

, इन के लिए अपने दृश्य के प्रत्येक कुछ ऐसी दिखाई देगी: क्या बिल्ली वास्तव में यहाँ पर जा रहा है

<UserControl x:Class="Your.Namespace.MainView" 
      xmlns:views="clr-namespace:Your.Namespace.Views" 
      xmlns:cal="http://www.caliburnproject.org" 
      cal:Bind.Model="Your.Namespace.ViewModels.MainViewModel" 
      MinWidth="800" MinHeight="600"> 
    <StackPanel x:Name="RootVisual"> 
     <views:YourFirstView /> 
     <views:YourSecondView /> 
     <!-- other controls as needed --> 
    </StackPanel> 
</UserControl> 

XAML या बच्चों के विचारों

<UserControl x:Class="Your.Namespace.Views.YourFirstView" 
      xmlns:cal="http://www.caliburnproject.org" 
      cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel" 
      MinWidth="800" MinHeight="600"> 
    <Grid x:Name="RootVisual"> 
     <!-- A bunch of controls here --> 
    </Grid> 
</UserControl> 

में से एक?

ठीक है, सीएम बूटस्ट्रैपर में देखता है, कि मेनव्यूमोडेल public class AppBootstrapper : Bootstrapper<MainViewModel> निर्दिष्ट लाइन के कारण शुरुआती बिंदु है। MainViewModel की आवश्यकता है कि YourFirstViewModel और YourSecondViewModel (और अन्य व्यूमोडेल) इसके कन्स्ट्रक्टर में आवश्यक हों, इसलिए सीएम प्रत्येक को बनाता है। इन सभी व्यूमोडल्स आईओसी में समाप्त होते हैं (बाद में आपके जीवन को बहुत आसान बनाते हैं - फिर, एक पूरी चर्चा)।

C.M DataContext बताए हैंडल, अपनी ओर से, विचारों से प्रत्येक के लिए है क्योंकि आप जो वी एम की तरह cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel"

किसी भी भाग्य के साथ

लाइन के साथ करने के लिए बाध्य करने के लिए निर्दिष्ट करते हैं, कि मिलना चाहिए आप शुरू कर दिया। सीएम उदाहरण प्रोजेक्ट Caliburn.Micro.HelloEventAggregator का भी संदर्भ लें क्योंकि यह वही करता है जो आप खोज रहे हैं (हालांकि, इसे इवेंट एग्रीगेटर डेमो के रूप में वर्णित किया गया है, जो कि भी बहुत उपयोगी है - लेकिन फिर, एक और चर्चा)

(सम्मान के लिए मूल उत्तर, नीचे)

आप ऐसा करने की जरूरत:

<UserControl x:Class="Your.Namespace.Here.YourView" 
      xmlns:cal="http://www.caliburnproject.org" 
      cal:Bind.Model="Your.Namespace.Here.YourViewModel" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="1024"> 
    <YourControlLayout /> 
</UserControl> 

सूचना लाइन cal:Bind.Model="Your.Namespace.Here.YourViewModel" जो सटीक देखें मॉडल को यह देखें बाध्य करने के लिए निर्दिष्ट करता है।

अपनी कक्षा के प्रकार को निर्यात करना न भूलें, या c.m इसे नहीं ढूंढ सकता।

[Export(typeof(YourViewModel))] 
public class YourViewModel : IShell 
{ 
    ... 
} 

तो फिर तुम घोंसला आप के रूप में अपने उपयोगकर्ता नियंत्रण फिट देख सकते हैं। सीएम का उपयोग करने के लिए यह एक बहुत अच्छा तरीका है, और आप इसे अत्यधिक स्केलेबल पाएंगे। केवल कमजोरी यह है कि व्यू और व्यू मॉडेल एक ही प्रोजेक्ट में होना चाहिए (जहां तक ​​मैं कह सकता हूं)। लेकिन इस दृष्टिकोण की ताकत यह है कि आप चीजों को संगठित रखने के लिए, यदि आप चाहें तो अलग-अलग नामस्थानों (उसी प्रोजेक्ट के भीतर) में व्यू और व्यू मॉडल क्लास को अलग कर सकते हैं।

c.m मैं इस विधि पसंद करते हैं पर एक टिप्पणी के रूप में, वास्तव में, मैं घोंसला देखें UserControls और इस तरह की जरूरत नहीं है, भले ही। मैं स्पष्ट रूप से चुड़ैल वीएम घोषित करता हूं कि एक दृश्य बाध्य है (और अभी भी सीओएम को आईओसी में सभी भारी भारोत्तोलन को संभालने दें) ताकि c.m को "अंतर्निहित कोड" से बाहर निकाला जा सके।

यहां तक ​​कि एक अच्छा ढांचे के साथ

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

+0

यह बताते हुए कि यह कैसा होना चाहिए, धन्यवाद। Alhough, मैं इसे काम करने के लिए नहीं मिल सकता है। कृपया मेरी मूल पोस्ट देखें और अपडेट किए गए हिस्से की जांच करें। यह तय करना अच्छा लगेगा :) – diamondfish

+1

आप सही रास्ते पर हैं - हम बस मूर्खतापूर्ण कुछ खो रहे हैं। निर्यात पर जानकारी जोड़ा गया। – EtherDragon

+0

गह, यह सिर्फ काम नहीं करेगा: एस मैंने एक मेफबूटस्ट्रैप क्लास जोड़ने की कोशिश की और आईशेल इंटरफ़ेस को लागू किया, लेकिन अभी भी कुछ भी नहीं। आप समय अपने प्रोजेक्ट की जांच करने के लिए है, तो ऐसा करने के लिए संकोच न करें तो :) http://johanbjarnle.se/temp/CaliburnTest.rar – diamondfish

16

आपके मुख्य दृश्य पर ContentControl का उपयोग करने का एक बेहतर तरीका है, और इसे MainViewModel पर सार्वजनिक संपत्ति के समान नाम दें जो MyControlViewModel प्रकार है। जैसे

MainView.xaml

<ContentControl x:Name="MyControlViewModel" /> 

MainViewModel.cs

// Constructor 
public MainViewModel() 
{ 
    // It would be better to use dependency injection here 
    this.MyControlViewModel = new MyControlViewModel();  
} 

public MyControlViewModel MyControlViewModel 
{ 
    get { return this.myControlViewModel; } 
    set { this.myControlViewModel = value; this.NotifyOfPropertyChanged(...); } 
} 
+0

मैं इस काम मिल गया। लेकिन ऐसा लगता है कि सीएम का ज्यादा उपयोग नहीं किया जा रहा है? हालांकि इसे करने का एक अच्छा तरीका है, बहुत बहुत धन्यवाद! – diamondfish

+0

मुझे यह भी पता चला कि ContentControl का उपयोग करते समय मैं VS में संपादन करते समय मुख्य दृश्य में MyControl का इंटरफ़ेस नहीं देख सकता। क्या ऐसा करने के लिए कोई रास्ता है? – diamondfish

+2

आप मुख्यमंत्री उपयोग कर रहे हैं, कि क्या, अपने दृश्य मॉडल संपत्ति के नाम से ContentControl के नाम से मेल खाते है दृश्य लगाने, ContentControl में दृश्य इंजेक्शन लगाने, और दृश्य मॉडल गुण के लिए बाध्य दृश्य के नियंत्रण है। Caliburn.Micro के साथ संरचना देखने के लिए यह अनुशंसित दृष्टिकोण होगा। – devdigital

1

फ़ाइल App.xaml.cs में, विधि में GetInstance निम्नलिखित लाइनों

protected override object GetInstance(Type service, string key) 
{ 
    if (service == null && !string.IsNullOrWhiteSpace(key)) 
    { 
     service = Type.GetType(key); 
     key = null; 
    } 
    // the rest of method 
} 
+0

मेरे बूटस्ट्रैपर में निनजेक्ट का उपयोग करने पर मेरा मान फिक्स्ड शून्य त्रुटि नहीं हो सकता है। बहुत बहुत धन्यवाद :) – Dave