एमवीवीएम फ्रेंडली वे में डेटाग्रिड में एक नई पंक्ति कैसे जोड़ें

I have the following DataGrid

 ... 

I am using the MVVM pattern to bind to an ObservableCollection Resources and this works great. I have a button that adds a new row and this is done by adding a new ResourceViewModel to the Resources collection - great. Now, I want the user to be able to click on the empty last row, and this automatically creates a new record in the DataGrid.

मैंने सुनिश्चित किया है कि DataGrid में CanUserAddRows = True है। मैंने सुनिश्चित किया है कि संसाधन ( ResourceViewModel ) संग्रह में कक्षा है कि मैं एक डिफ़ॉल्ट कन्स्ट्रक्टर (कोई पैरामीटर नहीं) के लिए बाध्यकारी हूं और मैंने यह सुनिश्चित कर लिया है कि संग्रह प्रकार नहीं है सिफ़ पढ़िये। जब उपयोगकर्ता अंतिम पंक्ति पर क्लिक करता है तो डिफ़ॉल्ट कन्स्ट्रक्टर आग लगती है लेकिन नए ResourceViewModel ऑब्जेक्ट को सही ढंग से चालू करने के लिए संसाधन संग्रह के ग्रिड के संदर्भ में आवश्यकता होती है ...

I suppose I could use and AttachedCommand on the CellBeginEdit event and then add a new ResourceViewModel to the observable collection there, is there a standard way of doing this?


ध्यान दें, मैंने निम्नलिखित प्रश्न पढ़े हैं और ये मेरी कोई मदद नहीं कर रहे हैं

  1. wpf DataGrid - नई पंक्तियों के लिए ईवेंट?
  2. डेटाग्रिड और एमवीवीएम के साथ पंक्तियां कैसे जोड़ें

संपादित करें। यह पता चला है कि मुझे wpf DataGrid में एक बग के कारण ऐसा करने में समस्याएं आ रही हैं। निगेल स्पेंसर का ब्लॉग । हालांकि, इस समय मेरे फिक्स मेरे लिए काम नहीं कर रहा है ...

0
+1 अच्छा सवाल है।
जोड़ा लेखक Sheridan, स्रोत
निगेल स्पेंसर के ब्लॉग पोस्ट का अपडेट किया गया लिंक wpf DataGrid के साथ चयनित वैल्यू में बाध्यकारी समस्याएं है
जोड़ा लेखक Tone, स्रोत

2 उत्तर

जहां तक ​​मैं समझता हूं, आप जानते हैं कि अपने डेटा बाध्य संग्रह में नए आइटम को सही तरीके से कैसे जोड़ना है जिसके परिणामस्वरूप DataGrid में कोई नया आइटम जोड़ा जा रहा है और आपका प्रश्न वास्तव में इस बात से संबंधित है कि आप यह कैसे कर सकते हैं उपयोगकर्ता DataGrid में अंतिम पंक्ति पर क्लिक करता है। दृश्य मॉडल में कुछ ईवेंट को संभालने का सामान्य तरीका एक संलग्न संपत्ति (यदि कोई पहले से मौजूद नहीं है) बनाना है जो आपके लिए उस ईवेंट को संभालता है।

उदाहरण के लिए, आप संलग्न संपत्ति बना सकते हैं जो एक हैंडलर को प्रासंगिक ईवेंट और अन्य प्रकार के ICommand से जोड़ता है जिसे आप ईवेंट हैंडलर कहलाते समय निष्पादित कर सकते हैं। फिर आप अपने दृश्य मॉडल में उस ICommand की कार्यक्षमता लिख ​​सकते हैं (जिसमें आप अपने डेटा बाध्य संग्रह में एक नया आइटम जोड़ते हैं) और डेटा आपके ICommand कार्यान्वयन को < कोड> संलग्न आईसीओएमएंड संपत्ति ।

जैसा कि मुझे काफी यकीन है कि आप संलग्न संपत्ति s को परिभाषित करने के बारे में जानते हैं, मैं आपको दिखाकर आपको अपमानित नहीं करूंगा। अगर मैंने आपको गलत समझा है, या खुद को स्पष्ट नहीं किया है तो कृपया मुझे बताएं।

0
जोड़ा
उत्तर के लिए धन्यवाद। समस्या यह है कि मैंने InitializingNewItem ईवेंट पर आग लगाने के लिए एक संलग्न कमांड सेट किया है। जब मैं संपादन मोड में DataGrid की अंतिम पंक्ति डालता हूं और ग्रिड नए आइटम को बनाने का प्रयास करता है तो यह आग लग जाता है। यहां मैं नया आइटम जोड़ सकता हूं, लेकिन DataGrid डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करके आइटम को तुरंत चालू करने का प्रयास करता है। मैं ग्रिड को स्वचालित रूप से ऐसा करने से रोकने में सक्षम नहीं होना चाहता क्योंकि मैं आदेश और घटना का उपयोग कर सकता हूं जो मैं चाहता हूं ...
जोड़ा लेखक MoonKnight, स्रोत
तो मुझे लगता है कि सवाल बन जाता है, ऐसा करने का सबसे अच्छा तरीका क्या है; ए। नई पंक्ति जोड़ने के बाद ईवेंट को रद्द करें (कैसे, मुझे कोई जानकारी नहीं है)। बी। ग्रिड को यह स्वयं करने दें - लेकिन फिर डिफ़ॉल्ट ctor में ऑब्जेक्ट को सही तरीके से कैसे प्रारंभ किया जाए? क्या ऐसा करने का एक मानक तरीका है?
जोड़ा लेखक MoonKnight, स्रोत
आपके समय के लिए धन्यवाद...
जोड़ा लेखक MoonKnight, स्रोत
मैं शायद ही कभी इन नियंत्रणों का उपयोग करता हूं, इसलिए दुर्भाग्यवश, मैं वास्तव में उनके बारे में उन्नत सलाह देने में सक्षम होने की स्थिति में नहीं हूं। आपकी समस्या के साथ शुभकामनाएँ।
जोड़ा लेखक Sheridan, स्रोत

यहां एक संलग्न संपत्ति है जो पंक्तियों को जोड़ने के लिए कमांड पंजीकृत करती है (मानते हुए कि स्रोत संग्रह में एक सामान्य प्रकार तर्क है):

public static readonly DependencyProperty RegisterAddCommandProperty = DependencyProperty.RegisterAttached("RegisterAddCommand", typeof(bool), typeof(DataGridExtensions), new PropertyMetadata(false, OnRegisterAddCommandChanged));
public static bool GetRegisterAddCommand(DependencyObject obj)
{
    return (bool)obj.GetValue(RegisterAddCommandProperty);
}
public static void SetRegisterAddCommand(DependencyObject obj, bool value)
{
    obj.SetValue(RegisterAddCommandProperty, value);
}
static void OnRegisterAddCommandChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (sender is DataGrid)
    {
        var DataGrid = sender as DataGrid;
        if ((bool)e.NewValue)
            DataGrid.CommandBindings.Add(new CommandBinding(AddCommand, AddCommand_Executed, AddCommand_CanExecute));
    }
}

public static readonly RoutedUICommand AddCommand = new RoutedUICommand("AddCommand", "AddCommand", typeof(DataGridExtensions));
static void AddCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var DataGrid = sender as DataGrid;

    var ItemsSourceType = DataGrid.ItemsSource.GetType();
    var ItemType = ItemsSourceType.GetGenericArguments().Single();

    DataGrid.Items.Add(Activator.CreateInstance(ItemType));
}
static void AddCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = (sender as DataGrid).CanUserAddRows;
}

और फिर आप कमांड को इस तरह कहीं बटन पर लागू कर सकते हैं:

<button Command="{x:Static Extensions:DataGridExtensions.AddCommand}"/>

कमांड लक्ष्य निर्दिष्ट करना न भूलें।

0
जोड़ा