2009-06-26 16 views
9

के अंदर बाध्यकारी कमांड मैं वर्तमान में एक छोटी WPF प्रोजेक्ट को एमवीवीएम में परिवर्तित कर रहा हूं। मेरे पास मुख्य विंडो के व्यूमोडेल में List<CustomObject> है जो मेरे आइटम नियंत्रण प्रत्येक तत्व के यूआई को बनाने के लिए डेटा टेम्पलेट को बांधता है और उपयोग करता है। मेरे पुराने कोड ने एक क्लिक ईवेंट को संभालने के लिए DataTemplate के अंदर एक ईवेंट हैंडलर का उपयोग किया। मैं अपने कोड-बैक इवेंट हैंडलर को खत्म करने के लिए किसी प्रकार का कमांड बाध्यकारी उपयोग करना चाहता हूं, लेकिन मेरे आइटम्स कंट्रोल में आइटम्स का डेटाकॉन्टेक्स्ट मॉडल ऑब्जेक्ट है, इसलिए मैं वर्तमान में व्यूमोडेल से आईसीओएमएंड से जुड़ नहीं सकता हूं।डब्ल्यूपीएफ एमवीवीएम - एक आइटम कंट्रोल

तो, मुझे लगता है कि इस पर हमला करने के कुछ तरीके हैं और मुझे यकीन नहीं है कि यह करने का सबसे अधिक "एमवीवीएम" तरीका कौन सा होगा। क्या मैं आइटम्स कंट्रोल। इटम्ससोर्स को एक नई व्यू मॉडेल क्लास के संग्रह में जोड़ता हूं जो प्रत्येक आइटम का प्रतिनिधित्व करता है? या क्या मैं DataTemplate के बजाय UserControls का उपयोग करता हूं और फिर मैं प्रत्येक UserControl को इसे ViewModel के अपने उदाहरण में जोड़ सकता हूं जो इसका प्रतिनिधित्व करता है? या क्या कोई बाध्यकारी अभिव्यक्ति है जिसका उपयोग मैं विंडो के डेटाकॉन्टेक्स्ट को वापस देखने के लिए उपयोग कर सकता हूं ताकि व्यूमोडेल से जुड़ सकें (जैसा कि मैंने इसे टाइप किया है, यह सिर्फ खराब लगता है इसलिए मैं इसे बड़ा "नहीं" मान रहा हूं विचार)?

इसके अलावा, मैं अपने आदेश को बाध्य करना चाहता हूं वह ग्रिड नियंत्रण के वाममाउसबटनअप घटना है। ग्रिड के लिए कोई "कमांड" नहीं है, इसलिए मैं इनपुट बाइंडिंग का उपयोग करने का प्रयास कर रहा था। मैं एक स्थिर कमांड का उपयोग कर सकता हूं (जैसे कि अनुप्रयोग में निर्मित एक में से एक), लेकिन मैं एक आईसीओएमएंड उदाहरण से जुड़ने के लिए बाध्यकारी अभिव्यक्ति का उपयोग नहीं कर सकता जो कि व्यूमोडेल की संपत्ति है क्योंकि MouseBinding.Command निर्भरता प्रॉपर्टी नहीं है।

मैं एमवीवीएम में ईवेंट हैंडलिंग के विषय पर बहुत उलझन में हूं, इसलिए किसी भी और सभी जानकारी की सराहना की जाती है।

उत्तर

4

जोश स्मिथ ने एमएसडीएन here में एक उत्कृष्ट लेख लिखा जहां वह कमांड बाध्यकारी के बारे में बात करता है।

आपके मामले में यह इस करने पर निर्भर करता:

  • आप अपने के सभी को खत्म करने के कोड-पीछे नहीं होगा, लेकिन यह शायद अलग दिखेगा
  • आपका CustomObjects शायद वीएम शिम श्रेणियां होती हैं करना होगा , या रिलेकॉमैंड आर्किटेक्चर का लाभ उठाने के लिए खुद को वीएम बनाते हैं।

एचटीएच।

19

क्या मैं आइटम्सकंट्रोल.इटेम्ससोर्स को एक नई व्यू मॉडेल क्लास के संग्रह में जोड़ता हूं जो प्रत्येक आइटम का प्रतिनिधित्व करता है?

चाहे आप कमांड होस्ट करने के लिए कस्टम ऑब्जेक्ट व्यू मॉडेल बनाएं या उसी व्यूमोडेल के भीतर कमांड रखें, जिसमें सूची वास्तव में कार्यवाही के कार्य पर निर्भर करती है। क्या यह ऐसा कुछ है जो कस्टमऑब्जेक्ट से संबंधित है, या यह ऐसा कुछ है जो आपके वर्तमान व्यू मॉडेल से संबंधित है?

या वहां मैं (के रूप में मैं इस टाइप करें, यह सिर्फ इसलिए मैं एक संभालने हूँ बुरा लगता है ViewModel करने के लिए बाध्य करने के लिए उपयोग किया है खिड़की के DataContext करने के लिए वापस उल्लेख करने के लिए उपयोग कर सकते हैं अभिव्यक्ति बाध्यकारी किसी तरह का है इस विचार के लिए बड़ा "नहीं")?

यह उतना बुरा नहीं है जितना लगता है। विंडो की डेटाकॉन्टेक्स्ट की आपको वास्तव में डेटाकोंटेक्स्ट की आवश्यकता नहीं है, इससे पहले कि वह अलग-अलग आइटमों पर स्विच हो जाए।इसलिए यदि आपके आदेश एक ही ViewModel कि CustomObjects की सूची को होस्ट करता है पर था, आप इसे करने के CustomObject के DataTemplate से किसी एक से इन तरीकों में से किसी का उपयोग कर बाँध सकता है:

{Binding ElementName=uiCustomObjectsItemsControl, Path=DataContext.MyCommand} 
{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.MyCommand} 

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

इसके लिए, मैं Attached Command Behaviors जैसे कुछ का उपयोग करूंगा जो आपको किसी भी घटना में आईसीओएमएंड संलग्न करने देगा।

1

आप अपने कमान को अपने मॉडल में रखने की कोशिश कर सकते हैं।

public class MyModel 
{ 
    public MyModel() 
    { 
     MyCommand = new DelegateCommand(MyCommandExecute); 
    } 

    public ICommand MyCommandCommand { get; set; } 

    private void MyCommandExecute() 
    { 
    } 
} 

और फिर, आप के रूप में अपने ViewModel में अपने आइटम की सूची के लिए एक ObservableList होना आवश्यक है,

public class MyViewModel 
{ 
    public MyViewModel() 
    { 
     MyStarterCommand = new DelegateCommand(MyCommandExecute); 

     if (!IsDesignTime)//(bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(DependencyObject)).Metadata.DefaultValue; 
      MyCommand.Execute(null); 
    } 

    private ObservableCollection<MyModel> list; 
    private ICommand MyStarterCommand { get; set; } 

    public ObservableCollection<MyModel> List 
    { 
     get { return list; } 
     set 
     { 
      list = value; 
      RaisePropertyChanged(() => List); 
     } 
    } 

    private void MyStarterCommandExecute() 
    { 
     List = new ObservableCollection<MyModel>(); 

     //Fill the list here 
     List.Add(new MyModel()); 
    } 
} 

फिर XAML में तुम कहते हो जाना चाहिए;

<ItemsControl ItemsSource="{Binding List}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Button Content="MyButton" Command="{Binding MyCommand}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
संबंधित मुद्दे