2010-05-20 15 views
5

मैं अपने ज्ञान को विस्तृत करने के लिए एमवीवीएम डिज़ाइन पैटर्न का उपयोग करके सिल्वरलाइट 4 में नमूना गेम बनाने की कोशिश कर रहा हूं। मैं लॉरेन बग्नियन के एमवीएमएमलाइट टूलकिट का भी उपयोग कर रहा हूं (यहां पाया गया: http://mvvmlight.codeplex.com/)। मैं बस इतना करना चाहता हूं कि विशिष्ट कुंजी दबाकर कैनवास के भीतर चारों ओर एक आकार ले जाएं। मेरे समाधान में प्लेयर.एक्सएमएल (केवल एक आयताकार है; इसे चारों ओर ले जाया जाएगा) और MainPage.xaml (कैनवास और प्लेयर नियंत्रण का एक उदाहरण)।सिल्वरलाइट 4 + एमवीवीएम + कीडाउन इवेंट

मेरी समझ के लिए, सिल्वरलाइट सुरंग घुमावदार घटनाओं का समर्थन नहीं करता है, केवल बुलबुले। मेरी बड़ी समस्या यह है कि Player.xaml KeyDown ईवेंट को कभी पहचान नहीं लेता है। यह हमेशा मेनपेज.एक्सएमएल द्वारा पहले से अवरुद्ध होता है और यह कभी भी किसी भी बच्चे के नियंत्रण तक नहीं पहुंचता क्योंकि यह ऊपर की तरफ बुलबुले होते हैं। मैं चाहूंगा कि प्लेयर को प्लेयरव्यू मॉडेल क्लास में ले जाने के लिए तर्क हो, लेकिन मुझे नहीं लगता कि खिलाड़ी बिना किसी कुंजीडाउन घटनाओं के बारे में जान सकता है, बिना स्पष्ट रूप से उन्हें मुख्य पृष्ठ से नीचे गुजर रहा है।

मैंने मेनपेज व्यू मॉडेल क्लास में हैंडलर तर्क जोड़ना समाप्त कर दिया। अब मेरी समस्या यह है कि MainPageViewModel को Player.xaml का कोई ज्ञान नहीं है, इसलिए यह KeyDown ईवेंट को संभालने के दौरान इस ऑब्जेक्ट को स्थानांतरित नहीं कर सकता है। मुझे लगता है कि यह उम्मीद की जा रही है, क्योंकि ViewModels को उनके संबंधित दृश्यों का कोई ज्ञान नहीं होना चाहिए।

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

(MainPage.xaml)

<UserControl x:Class="MvvmSampleGame.MainPage" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:game="clr-namespace:MvvmSampleGame"    
     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
     xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4" 
     mc:Ignorable="d" 
     Height="300" 
     Width="300" 
     DataContext="{Binding Main, Source={StaticResource Locator}}"> 

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="KeyDown"> 
     <cmd:EventToCommand Command="{Binding KeyPressCommand}" PassEventArgsToCommand="True" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

<Canvas x:Name="LayoutRoot">  
    <game:Player x:Name="Player1"></game:Player> 
</Canvas> 

(MainViewModel.cs)

public MainViewModel() 
{ 

    KeyPressCommand = new RelayCommand<KeyEventArgs>(KeyPressed); 

}  

public RelayCommand<KeyEventArgs> KeyPressCommand 
{ 
    get; 
    private set; 
} 

private void KeyPressed(KeyEventArgs e) 
{ 

     if (e.Key == Key.Up || e.Key == Key.W) 
     { 
      // move player up 

     } 
     else if (e.Key == Key.Left || e.Key == Key.A) 
     { 
      // move player left 
     } 
     else if (e.Key == Key.Down || e.Key == Key.S) 
     { 
      // move player down 
     } 
     else if (e.Key == Key.Right || e.Key == Key.D) 
     { 
      // move player right 
     } 
} 

अग्रिम धन्यवाद, जेरेमी

+0

क्या आपके मेन व्यूमोडेल के पास आपके प्लेयर ऑब्जेक्ट तक पहुंच है? यदि ऐसा है, तो प्लेयर ऑब्जेक्ट पर MoveUp() नामक एक विधि नहीं हो सकती है, फिर कुंजी दबाए गए ईवेंट में आप केवल प्लेयर.मोवअप() को कॉल कर सकते हैं? इस तरह, प्लेयर की गति के लिए तर्क अभी भी प्लेयर ऑब्जेक्ट में होगा। – JSprang

+0

नहीं, इसमें प्लेयर ऑब्जेक्ट का संदर्भ नहीं है। इसका एक्सएएमएल का कोई संदर्भ नहीं है, इस तरह मैंने सोचा कि एमवीवीएम को काम करना चाहिए था। क्या कोई तरीका है कि मैं प्लेयर के अपने एक्सएएमएल इंस्टेंस को मेनव्यूमोडेल में एक चर में बांध सकता हूं? – jturinetti

उत्तर

3

इसके बजाय EventTrigger का उपयोग कर के, करने की कोशिश KeyTrigger का उपयोग करें और स्रोत ऑब्जेक्ट को लेआउट रूट के रूप में सेट करें।

एक और विकल्प (जो मुझे लगता है बेहतर है) ViewModel प्लेयर की स्थिति को संभालने देना है। उदाहरण के लिए, प्लेयरटॉप नामक एक संपत्ति और प्लेयर लिफ्ट नामक एक संपत्ति है। पीएलएयर के कैनवास को बांधें। टॉप और कैनवास। इनके लिए संपत्ति संपत्ति। जब उपयोगकर्ता कुंजी दबाता है, तो वीएम पर एक कमांड निष्पादित किया जाता है जो इन गुणों को अद्यतन करता है। इस तरह वीएम को यह नहीं पता होना चाहिए कि क्या स्थानांतरित किया गया है, या यह कैसे स्थानांतरित किया जाता है।

क्या यह समझ में आता है?

+0

धन्यवाद! मैं आपके बाद के सुझाव का उपयोग कर समाप्त हो गया। हालांकि मुझे एक और समस्या थी ... क्योंकि प्लेयर के पास अपने प्लेयरएव मॉडेल को अपने प्लेयरएव मॉडेल में यूजरकंट्रोल स्तर पर एक्सएएमएल में बाध्य किया गया था, प्लेयर के कैनवास। टॉप और कैनवास। मेनपेज.एक्सएएमएल में लिफ्ट बाइंडिंग प्लेयरटॉप/प्लेयर लाइफ गुण नहीं ढूंढ सके । मुझे प्लेयर के डेटाकॉन्टेक्स्ट को अपने ग्रिड रूट कंट्रोल पर बाध्य करना पड़ा। – jturinetti

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