हमारे पास एक लैंडिंग पृष्ठ वाला एक डब्ल्यूपीएफ ऐप है जिसमें लगभग एक दर्जन या उससे अधिक बटन सूचीबद्ध हैं, जो सभी उस प्रकार के नए विचारों/व्यूमोडेल पर जा रहे हैं। यह बोझिल होता जा रहा है। हमारे पास एक व्यूमोडेल है जो इन सभी को सूचीबद्ध करता है जो मूल रूप से इस तरह दिखते हैं:

    private void ExecuteViewProgramCommand()
    {
        OpenViewMessage message = new OpenViewMessage();
        CurrentViewModel = message.ViewModel = ViewModelLocator.ProgramVM;
        Messenger.Default.Send<OpenViewMessage>(message);
    }

मुझे यह कभी पसंद नहीं आया कि यह कैसे किया गया, क्योंकि यह DRY सिद्धांत का उल्लंघन करता है। दूसरी पंक्ति में उपरोक्त कोड में केवल एक चीज बदलती है, जहां इस कोड में क्या परिवर्तन होता है ViewModelLocator.ProgramVM। मुझे लैंडिंग पृष्ठ को फिर से बनाने, इसे और अधिक व्यवस्थित बनाने का काम सौंपा गया है और हम और अधिक लॉन्चिंग बटन जोड़ने जा रहे हैं। मुझे लगता है कि निर्भरता इंजेक्शन का उपयोग करना बेहतर होगा। इसके अलावा, मैं डिस्प्ले को फिर से डिज़ाइन करने की आवश्यकता को संबोधित करने की कोशिश कर रहा हूं, ताकि यह एक सूची में, बिखरे हुए बटन के बजाय, और वर्णानुक्रम में हो।

सबसे पहले मैं इस वर्ग के साथ आया:

public class Tile
{
    public string ModuleName { get; set; }
    public NamedViewModelBase ModuleViewModel { get; set; }
}

(NamedViewModelBase व्यूमोडेल का नाम है जो सभी व्यूमोडेल के लिए सामान्य है।) फिर मैंने इसका परीक्षण करने के लिए एक यूनिट टेस्ट घोषित किया और इसे यूनिट टेस्ट के भीतर घोषित किया:

List<Tile> tiles = new List<Tile>()
{
    new Tile()
    {
        ModuleName = "Program",
        ModuleViewModel = ViewModelLocator.ProgramVM
    },
    new Tile()
    {
        ModuleName = "Organization",
        ModuleViewModel = ViewModelLocator.OrganizationVM
    }
}

लेकिन यह जल्दी ही स्पष्ट हो गया कि यह गलत था। ViewModelLocator.ProgramVM के सेटर में असाइनमेंट प्रोग्राम के लिए व्यूमॉडल को इंस्टेंट कर देगा। मुझे यह नहीं चाहिए, मैं इसे तुरंत चालू करने की कॉल करना चाहता हूं, जैसे कि हमारे पास ViewModelLocator में है:

static public ProgramViewModel ProgramVM
{
    get
    {
        if (ServiceLocator.IsLocationProviderSet)
        {
            SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
            return ioc.GetInstanceWithoutCaching<ProgramViewModel>(Guid.NewGuid().ToString());
        }
        else
        {
            return null;
        }
    }
}

तो, मैं सोच रहा हूं कि मुझे मॉड्यूल व्यू मॉडेल संपत्ति को कुछ इस तरह घोषित करने के लिए टाइल वर्ग को बदलना होगा: public NamedViewModelBase ModuleViewModel { get; }। लेकिन मुझे नहीं पता कि सूची को परिभाषित करते समय मैं इसे कैसे चालू करूं। इसका समाधान करने का सही तरीका क्या है?

0
Rod 30 जिंदा 2020, 01:56
यदि आपके वीएम में न्यूनतम सीटीआर हैं (कोई डीबी कॉल इत्यादि नहीं, बस init) तो आप उनमें से एक अवलोकन योग्य चयन बना सकते हैं और एक सूचीदृश्य के लिए एक बटन को टेम्पलेट के रूप में उपयोग करने और उन्हें इस तरह प्रस्तुत करने के लिए असाइन कर सकते हैं। मुझे पता है कि IoC स्वतः समाधान समाधान का आभास देता है लेकिन यह वास्तव में वैश्विक चरों का एक गौरवशाली सेट है।
 – 
XAMlMAX
30 जिंदा 2020, 12:57
आपका प्रश्न थोड़ा अस्पष्ट है। Tile के आपके वर्तमान कार्यान्वयन को देखते हुए, आप इसकी ModuleViewModel प्रॉपर्टी को किसी भी व्यू मॉडल पर सेट कर सकते हैं। आपका यहाँ वास्तव में क्या मुद्दा है?
 – 
mm8
30 जिंदा 2020, 18:35
Mm8, समस्या यह सुनिश्चित कर रही है कि यदि कोई उपयोगकर्ता प्रोग्राम पर 3 बार क्लिक करता है, तो उन्हें हमेशा ProgramViewModel का एक नया उदाहरण मिलता है। जिस तरह से मैंने Tile वर्ग को लागू किया है, उन्हें वही उदाहरण मिलेगा, जिसकी मैं अनुमति नहीं दे सकता।
 – 
Rod
30 जिंदा 2020, 20:15
यह शायद सबसे अच्छा होगा यदि मैं दिखाऊं कि हम प्रोग्रामवीएम जैसे नए वीएम को कैसे इंस्टेंट करते हैं। निम्नलिखित कोड हमारे व्यूमोडेल लोकेटर से है: स्थिर सार्वजनिक प्रोग्राम व्यूमोडेल प्रोग्रामवीएम { प्राप्त करें {if (ServiceLocator.IsLocationProviderSet) {SimpleIoc ioc = ServiceLocator.Current as SimpleIoc; वापसी ioc.GetInstanceWithoutCaching(Guid.NewGuid().ToString()); } और {वापसी शून्य; } } }
 – 
Rod
30 जिंदा 2020, 20:47

2 जवाब

सबसे बढ़िया उत्तर

यह छद्म कोडिश सलाह होने जा रही है जो उसी ट्रैक पर है जहां आप पहले से हैं:

यह मानते हुए कि BaseViewModel आपके सभी व्यक्तिगत VM के लिए आधार वर्ग है

  1. एक शब्दकोश बनाएं<स्ट्रिंग, बेसव्यू मॉडेल>
  2. एप्लिकेशन प्रारंभ समय के दौरान इस शब्दकोश को भरें (आपकी टाइल सूची की तरह दिखेगा)

    सार्वजनिक शून्य PreCreateVMs () { शब्दकोश [कुंजी] = नया कंक्रीट व्यू मॉडेल टाइप (); // यहां नए वीएमएस जोड़ते रहें }

  3. Xaml में, अपने सभी बटनों को उसी कमांड से बाँधें जो एक स्ट्रिंग तर्क लेता है (या इसे Enum के साथ सुधारें)। प्रत्येक बटन के लिए सही स्ट्रिंग कुंजी पास करें। जैसे: अकाउंट्स बटन क्लिक से AccountVM लॉन्च होना चाहिए जो कि डिक्शनरी में "AccountVM" कुंजी के साथ संग्रहीत है।

  4. कमांड हैंडलर में - स्ट्रिंग का उपयोग करें, डिक्शनरी को सही व्यूमोडेल ढूंढें और इस ऑब्जेक्ट को CurrentViewModel पर असाइन करें

रखरखाव के दृष्टिकोण से - आपको एक नया व्यूमोडेल जोड़ने की आवश्यकता है, एक नए बटन के साथ xaml को अपडेट करना है, सही कमांड पैरामीटर स्ट्रिंग असाइन करना है। इस स्ट्रिंग कुंजी का उपयोग करें और PreCreateVMs विधि में सही VM जोड़ें।

1
Prateek Shrivastava 30 जिंदा 2020, 02:34

मैंने टाइल वर्ग को फिर से डिज़ाइन किया है। मुझे विश्वास है कि मुझे दूसरा पैरामीटर कमांड होने की आवश्यकता है। मैं पूछ रहा हूं कि क्या यह बेहतर कर सकता है। यहां टाइल की नई परिभाषा दी गई है और इसका एक उदाहरण है कि मैंने इसे कैसे लागू करने का प्रयास किया:

public class Tile
{
    public string ModuleName { get; set; }
    //public NamedViewModelBase ModuleViewModel { get; set; }
    public Action ThisCommand { get; set; }
}

और यहां बताया गया है कि मैंने इसे सूची के रूप में कैसे लागू करने का प्रयास किया:

List<Tile> tiles = new List<Tile>()
{
    new Tile()
    {
        ModuleName = "Program",
        ThisCommand = () => 
        {
            if (ServiceLocator.IsLocationProviderSet)
            {
                SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
                ioc.GetInstanceWithoutCaching<ProgramViewModel>(Guid.NewGuid().ToString());
            }
        }
    },
    new Tile()
    {
        ModuleName = "Organization",
        ThisCommand = () =>
        {
            if (ServiceLocator.IsLocationProviderSet)
            {
                SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
                ioc.GetInstanceWithoutCaching<OrganizationViewModel>(Guid.NewGuid().ToString());
            }
        }
    }
};

क्या मैं सही रास्ते पर हूं? क्या मुझे इसके बजाय tiles को एक शब्दकोश के रूप में परिभाषित करना चाहिए?

0
Rod 30 जिंदा 2020, 21:35