2013-01-12 34 views
6

अधिकांश WPF/EF ट्यूटोरियल केवल एक विंडो में डेटाबेस को कवर करते हैं। हालांकि, वास्तविकता में डेटा कई खिड़कियों में प्रदर्शित होता है। आप अक्सर पहली विंडो में एक रिकॉर्ड प्रदर्शित करते हैं और अगली खिड़कियों में संबंधित विवरणों में गहरी खुदाई करते हैं।WPF/Entity Framework के साथ कई विंडो में डेटा बाध्यकारी? संदर्भ पास या नहीं?

तो, यह मेरे परिदृश्य में भी मामला है। यहां आप मेरी डेटा संरचना और ui देख सकते हैं। असल में मैं ग्राहकों और चालानों से निपट नहीं रहा हूं, लेकिन संरचना एक जैसी है। (मेरे ठोस सवाल अंत में कर रहे हैं।)

db design and ui mockup

InvoicesWindow में मैं एक चालान और प्रेस "शो चालान" चुन सकते हैं। इससे ग्राहक विवरण और उसके चालान प्रदर्शित करने वाले ग्राहकविंडो खुलते हैं। सही चालान पूर्व-चयनित है। ग्राहकविंडो में प्रदर्शित प्रत्येक चालान में मैं आइटम जोड़ सकता हूं या उन्हें संपादित कर सकता हूं। यह "आइटमविंडो" नामक एक अलग खिड़की में किया जाता है। डेटाग्रिड्स को संपादित करना एक विकल्प नहीं है। वे केवल पढ़ने के लिए सेट हैं।

यहाँ (मैं केवल अभी तक डेटा प्रदर्शित किया है, बचत नहीं) WPF खिड़की वर्गों के कोड है:

चालान विंडो:

public partial class InvoicesWindow : Window 
{ 
    private MyEntities context = new MyEntities(); 

    public InvoicesWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     CollectionViewSource invoicesViewSource = (CollectionViewSource)FindResource("invoicesViewSource"); 
     invoicesViewSource.Source = context.Invoices; 
    } 

    private void ShowInvoice_Click(object sender, RoutedEventArgs e) 
    { 
     Invoice selectedInvoice = (Invoice)InvoicesDataGrid.SelectedItem; 
     var customerWindow = new CustomerWindow(selectedInvoice); 
     customerWindow.ShowDialog(); 
    } 
} 

ग्राहक विंडो:

public partial class CustomerWindow : Window 
{ 
    private MyEntities context = new MyEntities(); 
    private Invoice selectedInvoice; 

    public CustomerWindow() 
    { 
     InitializeComponent(); 
    } 

    public CustomerWindow (Invoice selectedInvoice) 
    { 
     InitializeComponent(); 
     this.selectedInvoice = selectedInvoice; 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     //Set the data 
     CollectionViewSource customerViewSource = (CollectionViewSource)FindResource("customerViewSource "); 
     customerViewSource.Source = context.Customers.Where(p => p.id == selectedInvoice.Customer.id); 

     //Select the right invoice 
     CollectionViewSource customerInvoicesViewSource = (CollectionViewSource)FindResource("customerInvoicesViewSource "); 
     customerInvoicesViewSource.Items.MoveCurrentTo(((ObjectSet<Invoice>)customerInvoicesViewSource.Source).Where(p => p.id == selectedInvoice.id).SingleOrDefault()); 
    } 

    private void EditItem_Click(object sender, RoutedEventArgs e) 
    { 
     Item selectedItem = (Item)ItemsDataGrid.SelectedItem; 
     var itemWindow = new ItemWindow((IQueryable<Customer>)(customerViewSource.Source),selectedInvoice,selectedItem); 
     itemWindow.ShowDialog(); 
    } 
} 

आइटम विंडो:

public partial class ItemWindow : Window 
{ 

    private Invoice _selectedInvoice; 
    private Invoice _selectedItem; 
    private IQueryable<Customer> _customers; 

    public ItemWindo() 
    { 
     InitializeComponent(); 
    } 

    public ItemWindow(IQueryable<Customer> customers, Invoice selectedInvoice, Item selectedItem) 
    { 
     InitializeComponent(); 
     this._customers = customers; 
     this._selectedInvoice = selectedInvoice; 
     this._selectedItem = selectedItem; 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     //Set the data 
     CollectionViewSource customerViewSource = (CollectionViewSource)FindResource("customerViewSource"); 
     invoicesViewSource.Source = _customers; 

     //Select the right invoice 
     CollectionViewSource customerInvoicesViewSource = (CollectionViewSource)FindResource("customerInvoicesViewSource "); 
     customerInvoicesViewSource.Items.MoveCurrentTo(_selectedInvoice); 

     //Select the right item 
     CollectionViewSource customerInvoicesItemsViewSource = (CollectionViewSource)FindResource("customerInvoicesItems"); 
     customerInvoicesItems.Items.MoveCurrentTo(_selectedItem); 
    } 

} 

मैंने अपने दिमाग से कोड लिखा था। तो, शायद कुछ जानवर गायब हैं और कुछ विधियां गलत वर्तनी हैं। मुझे उम्मीद है कि मुझे "ऑब्जेक्टसेट" के साथ सही प्रकार मिल गया है, यह "ऑब्जेक्ट कोलेक्शन" या ऐसा कुछ भी हो सकता है। बंधन के डिजाइन मैं सही लागू किया)

  • है; http://msdn.microsoft.com/de-de/data/ff806174.aspx

    तो, अंत में मेरे सवालों का:

    XAML इस वीडियो में तरह VS2010 की सहायता से व्यापक रूप से बनाया गया था?

    • ग्राहकविंडो में मैं एक नया संदर्भ बनाता हूं।
    • ग्राहकविंडो और आइटमविंडो के बीच मैं बस एक ही संदर्भ के डेटा को पास करता हूं और वर्तमान आइटम को मैन्युअल रूप से चुनता हूं।
    • ग्राहकविंडो में मैं ग्राहकों के लिए स्रोत के रूप में एकल प्रविष्टि के साथ ऑब्जेक्टसेट (या ऑब्जेक्ट कोलेक्शन, अब मैं इस प्रकार के बारे में निश्चित नहीं हूं) का उपयोग करता हूं। यह ठीक काम करता है। हालांकि, संग्रह की कोई आवश्यकता नहीं है, क्योंकि मैं केवल एक ग्राहक को संपादित करता हूं। मैंने एक ग्राहक को स्रोत के रूप में सेट करने का प्रबंधन नहीं किया। मुझे नहीं पता था कि वीएस -2010 द्वारा उत्पन्न दृश्य स्रोत को कैसे समायोजित किया जाए।
  • मैंने अभी तक बचत नहीं की है। लेकिन मुझे लगता है कि मैं ग्राहकविंडो और आइटमविंडो के बीच अपने डिजाइन के कारण समस्याओं में भाग लेने जा रहा हूं। शायद आप मुझे कुछ सलाह दे सकते हैं।
    • जब "लागू करें" - आइटमविंडो में बटन दबाया जाता है, तो आइटम डेटा डीबी में अपडेट किया जाना चाहिए।लेकिन ग्राहक- और ग्राहक के अंदर चालान से संबंधित डेटा नहीं है।
    • आइटमविंडो को बंद करते समय ग्राहकविंडो में आइटम का डेटाग्रिड अपडेट होना चाहिए। लेकिन ग्राहकविंडो में शेष फ़ील्ड नहीं, क्योंकि यहां आइटमविंडो खोलने से पहले डेटा बदल दिया जा सकता था।
    • "सिंक्रनाइज़ेशन समस्या" को दूर करने के लिए मेरे लिए एकमात्र समाधान: उपयोगकर्ता को "नया आइटम" या "आइटम संपादित करें" दबाए जाने से पहले "लागू करें" दबाकर मजबूर होना पड़ता है, यदि कोई परिवर्तन हुआ हो। (दो मॉनीटर के साथ काम करते समय विंडोज 7 के "विंडो रिज़ॉल्यूशन कंट्रोल" की तरह किंडा) लेकिन यह बहुत उपयोगकर्ता के अनुकूल नहीं है।
+0

आपने नकली बनाने के लिए क्या उपयोग किया? –

+0

@ बेंजामिन मैंने Google ड्राइव का उपयोग किया> इस तेजी से चित्रकारी। Google ड्राइव के कई फायदे हैं: यह सरल, तेज़ है, आप इसे वेब पर सहयोग, चर्चा या प्रकाशित कर सकते हैं। विंडोज अनुप्रयोगों के लिए बेहतर मॉकअप के लिए मैं माइक्रोसॉफ्ट विसियो का उपयोग करता हूं जिसमें कई विंडोज नियंत्रणों के लिए टेम्पलेट्स हैं। – OneWorld

+0

अब मैंने इसे कैसे कार्यान्वित किया है इसके बारे में थोड़ा अपडेट: अब तक, मुझे संदर्भ में पास करने और व्यू में CurrentItem में हेरफेर करने के लिए अब और कुछ अजीब नहीं लगता है। अब मैं इनवॉइस और ग्राहक विंडो के बीच भी पास करता हूं। मैंने आइटम "विन्डो" से बटन को "लागू करें" हटा दिया। ग्राहकविंडोज़ में लागू या ठीक क्लिक करते समय परिवर्तन केवल डीबी में संग्रहीत किए जाएंगे। आइटमविंडो में जब "रद्द करें" दबाया जाता है तो मैं डेटा को पुनर्स्थापित करने के लिए निम्न कार्य करता हूं: 'context.Refresh (RefreshMode.StoreWins, चयनित इटैम);' – OneWorld

उत्तर

0

एक क्लीनर डिजाइन MVVM डिजाइन पैटर्न का उपयोग करने के लिए किया जाएगा।

दृश्य मॉडल को विंडो के संदर्भ में इंजेक्ट करें और दृश्य मॉडल को या तो इकाइयों या एक इकाई के संग्रह में बाध्य करें, दृश्य मॉडल में गुणों के लिए xaml में बाध्य करें और दृश्य मॉडल में लागू आदेशों का उपयोग करें क्रियाएं उदाहरण के लिए नया जोड़ें, हटाएं।

खिड़कियों को संदर्भ के बारे में पता नहीं होना चाहिए।

यदि आपके पास एक सूची दृश्य मॉडल + विंडो और एक विवरण विंडो (अधिमानतः एक दृश्य मॉडल के साथ) है, तो सूची दृश्य मॉडल को चयनित आइटम को संदर्भ दृश्य मॉडल (या विंडो) में संदर्भ के रूप में पास करना चाहिए।

यदि खिड़कियां एक ही समय में खुली नहीं हैं या संबंधित वस्तुएं नहीं हैं, तो उनके विचार मॉडल को डेटाबेस संदर्भ साझा नहीं करना चाहिए, अन्यथा, विंडोज़ के बीच आसानी से प्रतिबिंबित होने के लिए, उनके पास डेटाबेस संदर्भ साझा करने के लिए।