2010-02-23 17 views
7

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

का उपयोग WPF मैं एक datatrigger कि में कुछ संपत्ति को बांधता है बना सकते हैं व्यूमोडेल और फिर गुई में परिवर्तन करता है। चूंकि मेरे पास सिल्वरलाइट में डेटाैट्रिगर नहीं है, इसलिए डेटाैट्रिगर (साफ कोड, यदि संभव हो तो एक ही स्थान पर) को प्राप्त करने के लिए सबसे समझदार तरीका क्या होगा?

(I posted a similar question, but it was worded poorly)

उत्तर

7

ऐसा करने का मेरा मानक तरीका दृश्य मॉडल (सामान्य रूप से एक enum) से एक "ViewState" संपत्ति का पर्दाफाश करने के लिए है। दृश्य तब संपत्ति से जुड़ा हुआ है और enum के आधार पर उपयुक्त दृश्य राज्यों में स्विच करने के लिए विजुअलस्टेटमैनगर का उपयोग करता है।

Expression Samples से DataStateSwitchBehavior दृश्य राज्यों में स्विचिंग करने के तरीके पर एक अच्छा उदाहरण है।

संपादित जवाब में बंद टिप्पणी करने के लिए

सबसे पहले, जब VisualStates के साथ काम कर ब्लेंड (कोई भी हाथ से इतना XAML लिखने के लिए मजबूर किया जाना चाहिए) का उपयोग करें। मेरा मानना ​​है कि यह एमएसडीएन सब्सक्रिप्शन के सभी (सबसे?) पर भी है।

दृश्य स्टेट्स का उपयोग Visual State Manager

<VisualStateManager.VisualStateGroups> 
    <VisualStateGroup x:Name="GroupOne"> 
     <VisualState x:Name="Normal"/> 
     <VisualState x:Name="Searching"/> 
    </VisualStateGroup> 
</VisualStateManager.VisualStateGroups> 

साथ शुरू होता है आप आमतौर पर layoutroot में जोड़ना चाहते हैं।

दृश्य स्थिति प्रबंधक में राज्य समूह का संग्रह होता है जो बदले में विजुअलस्टेट्स का संग्रह होता है।

समूह पारस्परिक रूप से अनन्य राज्यों को व्यवस्थित रखते हैं, क्योंकि आप किसी भी समय कई दृश्य राज्य सक्रिय हो सकते हैं लेकिन प्रत्येक समूह से केवल एक ही राज्य हो सकते हैं। मानक पैटर्न एक खाली राज्य होना है जिसे "सामान्य" या "डिफ़ॉल्ट" जैसे कुछ अन्य राज्यों को बंद करने के लिए कहा जाता है। आधारभूत आधार मूल रूप से।

अपने मामले में आप फिर एक "सर्च कर रहे हैं" दृश्य राज्य है जो एक स्टोरीबोर्ड जो विभिन्न बटन को निष्क्रिय होता होते हैं होगा, व्यस्त एनिमेशन को सक्रिय आदि

+0

तो क्या मैं अपने नियंत्रण पर दृश्य राज्यों को परिभाषित कर सकता हूं (एक बालविंडो पर भी?) और फिर उन्हें डेटास्टेटस्विचबैवियर का उपयोग करके स्विच कर सकते हैं? उदाहरण के लिए, एक राज्य 'SearchInProgress' हो सकता है। बटन को अक्षम करने के लिए मैं वीएसएम का उपयोग कैसे कर सकता हूं ताकि नियंत्रण 'SearchInProgress' में नियंत्रण के दौरान क्लिक करने योग्य न हो? –

+0

धन्यवाद ग्रीम। मुझे यह एक नमूना परियोजना में काम करने के लिए मिला और ऐसा लगता है कि यह जाने का रास्ता है। हालांकि, मुझे यहां उल्लिखित एक ही समस्या में भागना प्रतीत होता है: http://stackoverflow.com/questions/2118814/how-can-i-use-visualstates-in-a-childwindow। वीएसएम बाल खिड़कियों में काम नहीं कर रहा है। अब मैं सबकुछ उपयोगकर्ता नियंत्रण में रखूंगा और संदर्भ दूंगा कि बच्चे की खिड़की में। मैं DataStateSwitcher का उपयोग कर रहा हूं जिसका आपने इसे ViewModel-driven बनाने के लिए उल्लेख किया है। –

0

handiest तरीका सिल्वरलाइट Toolkit से BusyIndicator उपयोग करने के लिए है मुझे लगता है कि। चूंकि यह पूरे क्षेत्र को मुखौटा करता है जिसे आप इसे लागू करते हैं, सभी बटन स्वचालित रूप से अक्षम हो जाते हैं।

रद्द करें बटन के लिए आपको BusyIndicator के टेम्पलेट को संपादित करना होगा ताकि मुझे लगता है कि लोड एनीमेशन के ठीक आगे है।

आप बस BusyIndicator की IsBusy संपत्ति को अपने व्यूमोडेल में संबंधित संपत्ति में जोड़ देंगे जिसे आपने लोड करने से पहले सेट किया था और रीसेट करने से पहले रीसेट किया था।

0

मेरा समाधान ग्रीम ब्रैडबरी के समान है, लेकिन मैं डेटास्टेट स्विचवियर का उपयोग नहीं करता, क्योंकि यदि मेरा एक्स नियंत्रण एक टैब पैनल (या कुछ समान) के अंदर रखा गया है और जब मैं किसी अन्य टैब पर हूं, तो राज्य बदलता है, तो मैं ' एक अपवाद प्राप्त होगा ('तत्व' नहीं मिला ..)। अपवाद फेंक दिया गया है क्योंकि मेरा एक्स नियंत्रण अनलोड किया गया है जबकि मैं एक और टैब पर हूं और जिन तत्वों को अद्यतन करने की आवश्यकता है, वे नहीं मिलते हैं।

तो यहाँ मैं क्या कर रहा है:

मेरे विचार मॉडल में मैं एक संपत्ति VisualState एक सूचना संदेश भेजता है जब एक राज्य में परिवर्तन (मैं MVVM light toolkit का उपयोग करें):

private string visualState = XVisualStates.InitialState; 
    public string VisualState 
    { 
     get 
     { 
      return visualState; 
     } 

     set 
     { 
      visualState = value; 
      Messenger.Default.Send(new XStateChangedMessage(value)); 
     } 
    } 

और मेरा विचार के कोड में पीछे मैं एक अधिसूचना की सदस्यता:

public partial class XControl : UserControl 
{ 
    private string visualState = XVisualStates.InitialState; 
    public XControl() 
    { 
     InitializeComponent(); 

     //go to state when view is loaded 
     Loaded += (s, e) => ChangeState(); //every time a view is loaded go to current state 

     //change visual state when a notification is received 
     Messenger.Default.Register<XStateChangedMessage>(this, 
      state => 
      { 
       visualState = state.CurrentState; //save current state 
       ChangeState(); 
      }); 
    } 

    void ChangeState() 
    { 
     try 
     { 
      VisualStateManager.GoToState(this, visualState, true); //will throw an exception if current view is unloaded 
     } 
     catch 
     { 
      //NOTE: supress 'element' not found errors if user navigated to another view and state changes 
     } 
    } 
} 

और XStateChangedMessage एक साधारण वर्ग है:

public class XStateChangedMessage 
{ 
    public string CurrentState { get; private set; } 

    public XStateChangedMessage (string currentState) 
    { 
     CurrentState = currentState; 
    } 
} 
0

1) आप मॉडल मॉडल में IsEnabledSearch प्रॉपर्टी जैसे कुछ बना सकते हैं, और इसे बटन की IsEnabled या दृश्यता प्रॉपर्टी से जोड़ सकते हैं (आपको दृश्यता कनवर्टर के लिए एक बूल की आवश्यकता होगी)। इसके लिए नए दृश्य राज्य बनाना बहुत ही कुशल नहीं है, क्योंकि इस बटन का समर्थन करने के लिए आपके बटन में पहले से ही सभी तरह के दृश्य राज्य हैं।

2) Jounce mvvm ढांचे में ViewModel से VisualStates का समर्थन करने के लिए एक बहुत अच्छा कार्यान्वयन है; Jounce Visual State Manager