2012-08-15 36 views
6

मैं कैलिबर्न के लिए नया हूं। माइक्रोरो और मैं सोच रहा हूं कि मेरे एप्लिकेशन में उपयोगकर्ता लॉगिन/लॉगआउट चक्रों को संभालने का सबसे अच्छा तरीका क्या है। मैंने एक खाली शेल-व्यू का उपयोग करके इसे लागू करने के लिए कुछ सुझाव ऑनलाइन देखे जो लॉगिनव्यू और मुख्य एप्लिकेशन व्यू के बीच स्विच करता है, प्रत्येक में एक कस्टम व्यू मॉडेल के साथ।मैं कैलिबर्न में लॉगिन/लॉगआउट कैसे संभाल सकता हूं। माइक्रो?

मुझे वास्तव में यह समाधान पसंद नहीं है, क्योंकि मेरे लिए यह बहुत अलग गुणों (शीर्षक, चिह्न, आकार) के साथ 2 अलग-अलग खिड़कियां हैं और ऐसा लगता है कि एक अशुद्ध समाधान दो खिड़की एक दूसरे की तरह दिखता है। एक और समस्या यह है कि लॉग इन विंडो एक यूटिलिटी लाइब्रेरी से आती है जिसे मैं नियंत्रित नहीं करता हूं और जो कैलिबर्न का उपयोग नहीं करता है। माइक्रो, यह एक सादा पुरानी विंडो है जो मुझे एक घटना देता है जब उपयोगकर्ता "लॉगिन" पर क्लिक करता है।

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

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

तो मेरी प्रश्न हैं:

  1. आप इस समाधान के बारे में क्या सोचते हैं और आप किसी अन्य/बेहतर एक है क्या करते हो?
  2. मैं इसे कैसे कार्यान्वित करूं? ;-)

बहुत बहुत धन्यवाद!

+0

जब आप कहते हैं कि "सादे पुराने विंडो" करना आप डब्ल्यूपीएफ या WinForms? लॉगिन विंडो भी उपयोगकर्ता को प्रमाणीकृत करने का वास्तविक काम करता है या आपको "लॉगिन" ईवेंट को संभालना होगा और ऐसा करना होगा? – Kioshiki

+1

WPF विंडो और यह एक लॉगिन ईवेंट उठाता है जिसे मैं अपने आईओसी कंटेनर से प्राप्त प्रमाणीकरण सेवा का उपयोग करके संभालता हूं। – aKzenT

उत्तर

16

मुझे लगता है कि आपकी समस्या का समाधान काफी आसान है।

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

सबसे पहले एक अंतरफलक IShell जो दो प्रतिनिधियों LoginSuccessful और Logout

public interface IShell 
    { 
     Action LoginSuccessful { get; set; } 
     Action Logout { get; set; } 
    } 

अगला बनाने एक वर्ग ShellViewModel जो लागू करता IShell

public class ShellViewModel : Screen, IShell 
    { 
     public ShellViewModel() 
     { 
      LoginSuccessful = delegate { }; 
      Logout = delegate { }; 
     } 

     public Action LoginSuccessful { get; set; } 
     public Action Logout { get; set; } 

     public void DoLogin() 
     { 
      LoginSuccessful(); 
     } 

     public void DoLogout() 
     { 
      Logout(); 
     } 
    } 

तरीकों DoLogin और DoLogout क्रिया जो हो सकता है को उजागर करता है बनाने Button या जो भी आपके लिए उपयुक्त नियंत्रण है।

अगला चरण आपके बूटस्ट्रैपर में OnStartupMethod को ओवरराइड करना है। यह परिसर है कि आपके पास WindowManager और ShellViewModel का उदाहरण है जो आपकी पसंद के आईओसी फ्रेमवर्क द्वारा निर्यात किया गया है।

protected override void OnStartup(object sender, StartupEventArgs e) 
     { 
      var windowManager = IoC.Get<IWindowManager>(); 
      var viewModel = IoC.Get<IShell>(); 

      viewModel.LoginSuccessful = 
       () => GuardCloseAndReopen("Content"); 

      viewModel.Logout = 
       () => GuardCloseAndReopen("Login"); 

      windowManager.ShowWindow(viewModel, "Login"); 
     } 

     private void GuardCloseAndReopen(string shellViewMode) 
     { 
      var windowManager = IoC.Get<IWindowManager>(); 
      var shellScreen = IoC.Get<IShell>() as Screen; 

      Application.ShutdownMode = ShutdownMode.OnExplicitShutdown; 

      shellScreen.TryClose(); 

      Application.ShutdownMode = ShutdownMode.OnLastWindowClose; 

      windowManager.ShowWindow(shellScreen, shellViewMode); 
     } 

चाल इस के लिए है: DoLogout विधि कहा जाता है, तो वर्तमान विंडो ShellViewModel पर TryClose फोन करके बंद कर दिया जाता है। साथ ही आप Application.ShutdownMode को OnExplicitShutdown पर सेट करके एप्लिकेशन को शट डाउन होने से रोकते हैं। फिर विंडोमैनगर का उपयोग करके, आप विंडो मैनेजर को संदर्भ जानकारी के रूप में "लॉगिन" पास करके लॉगिन मोड में एक और विंडो बनाते हैं। यह वास्तव में एक ही दृश्य मॉडल है, हालांकि, एक अलग दृश्य प्रतिनिधित्व के साथ।

Logout के लिए आप बस एक ही चीज़ कर रहे हैं।

इस Caliburn कन्वेंशनों का उपयोग कर काम कर रहा है, तो आप एक विशेष परियोजना संरचना के रूप में यहाँ देखा की जरूरत प्राप्त करने के लिए (और there समझाया गया है): enter image description here

अब मैं आप को चुनौती देने के लिए इस कोड को लेने के लिए और एक छोटे से नमूना आवेदन बनाने के लिए। Login देखें (जो किसी बटन या जो कुछ भी लॉगिन करता है) बनाएं और Content लॉग इन असफल/लॉगआउट विधियों का उपयोग करके लॉगआउट बटन के साथ देखें।

यह आपके मुद्दे को न्यूनतम कोड और कक्षाओं के साथ हल करेगा। उम्मीद है कि यह आपके लिए सहायक होगा।

+0

मुझे दिलचस्पी है कि यह कैसे काम करेगा। आपके उदाहरण में शैलव्यूमोड क्या है? क्या यह ShellViewModel हो सकता है या शायद सिर्फ एक स्ट्रिंग? इसके अलावा aKzenT ने कहा कि लॉगिन विंडो पहले से मौजूद है, तो यह आपके डिज़ाइन को कैसे प्रभावित कर सकता है? – Kioshiki

+0

शैलव्यूमोड एक टाइपो था। बेशक यह खिड़की प्रबंधक को संदर्भ जानकारी पास करने वाली एक स्ट्रिंग है। आप इस संदर्भ को एक enum पर भी सेट कर सकते हैं, जो एक अच्छा विचार होगा। मौजूदा लॉगिन विंडो के लिए इस xaml को login.xaml पर डालें और UI को मौजूदा मोड में दृश्य मॉडल में सेट करें। यह जटिल नहीं हो सकता है क्योंकि ज्यादातर समय लॉगिन संवाद उपयोगकर्ता नाम/पासवर्ड टेक्स्टबॉक्स के साथ एक लॉगिन/रद्द बटन होते हैं। Autorisation को ShellViewModel द्वारा किया जा सकता है या कुछ तर्क प्रतिनिधि के साथ इंटरफ़ेस का विस्तार इस तर्क को रद्द करने और इसे रनटाइम के दौरान परिवर्तनीय बनाने के लिए किया जा सकता है। –

+1

मैंने सोचा था कि इस मामले में एक स्ट्रिंग सही थी, जैसा कि आप कहते हैं कि एक enum बेहतर होगा। मुझे लगता है कि आपको अभी भी मौजूदा लॉगिन विंडो के साथ एक ही विचार नहीं मिला है (हालांकि मुझे गलत विचार हो सकता है)।मैं ऐसी स्थिति के बारे में सोच रहा हूं जहां आपको एक बाइनरी असेंबली से मौजूदा विंडो का उपयोग करना है, शायद एक कंपनी में उनके पास एक डब्ल्यूपीएफ विंडो है या यहां तक ​​कि एक विंडोज़फॉर्म फॉर्म भी है जिसका उपयोग लॉगिन प्रक्रिया के लिए किया जाना चाहिए जो घटनाओं को उजागर करता है (देय हो सकता है) सत्यापन आदि के लिए)। मुझे लगता है कि एक साफ समाधान खोजने में काफी मुश्किल होगी। – Kioshiki

3

मुझे कुछ ऐसा करने में जाना पड़ा जो मूल रूप से काम करता है लेकिन शायद वास्तव में उपयोग करने योग्य होने के लिए थोड़ा और काम चाहिए। मेरी वेबसाइट पर Caliburn.Micro Login Window sample इस पोस्ट पर पूरी तरह से टिप्पणियां और स्रोत मिल सकते हैं।

मैंने कैलिबर्न के IEventAggregator का उपयोग किया। माइक्रो दो खिड़कियों के बीच संक्रमण को नियंत्रित करने के लिए। आप इस कोड लॉगिन स्क्रीन खोलने के लिए मिलता है:

public void Handle(LoginEvent message) 
{ 
    LoginWindow loginWindow = new LoginWindow(); 
    loginWindow.Login += new EventHandler<LoginEventArgs>(this.LoginWindow_Login); 
    loginWindow.Cancel += new EventHandler(LoginWindow_Cancel); 
    loginWindow.ShowDialog(); 
} 

इस एक ही स्रोत पहली बार दोनों एप्लिकेशन को खोलता है और जब लॉगआउट घटना प्रकाशित किया जाता है के लिए प्रयोग किया जाता है। लॉगआउट घटना इस तरह दिखता है:

public void Handle(LogoutEvent message) 
{ 
    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; 
    message.Source.TryClose(); 
    Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose; 
    this.events.Publish(new LoginEvent()); 
} 

जब एक लॉगिन यह मुख्य विंडो जो एक ViewModel पर आधारित है खोलने के लिए इस कोड का उपयोग करता है सफल हुआ:

ContentViewModel viewModel; 
viewModel = IoC.Get<ContentViewModel>(); 
viewModel.Username = e.Username; 
this.windowManager.ShowWindow(viewModel);