2010-02-21 18 views
16

क्या मूल्य परिवर्तक का उपयोग संसाधनों के रूप में पहले से परिभाषित किए बिना करना संभव है?डब्ल्यूपीएफ में मूल्य कनवर्टर्स का उपयोग संसाधनों के रूप में उन्हें परिभाषित किए बिना पहले

अभी मैं नहीं यह संभव नहीं होगा

<Window.Resources> 
    <local:TrivialFormatter x:Key="trivialFormatter" /> 
</Window.Resources> 

और

<Button Width="{Binding Width, ElementName=textBox1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource trivialFormatter}}" Height="50"> 

है कि बजाय Window.Resources में trivialFormatter संसाधन घोषित करने के लिए होने के, मैं इसे सीधे से जानकारी दे सकती है बटन की चौड़ाई बाध्यकारी? जैसे

Converter = {local:TrivialFormatter} 

धन्यवाद

उत्तर

22

सिंगलटन प्रकार IValueConverter रों के मामले (जैसे वे वर्तमान बंधन उदाहरण से किसी भी राज्य की जरूरत नहीं है) मैं स्थिर कन्वर्टर्स उपयोग करते हैं, यानी में:

Converter={x:Static SomeNamespace:SomeConverter.Instance} 

वहाँ भी डॉ द्वारा एक महान पोस्ट है WPF को क्लीनर इनलाइन here बनाने के लिए मार्कअप एक्सटेंशन का उपयोग करने पर।

+0

मार्कअप एक्सटेंशन के साथ अच्छी चाल! आपके पहले उदाहरण पर, हालांकि, आपको वीसी का स्थिर उदाहरण बनाने की आवश्यकता नहीं है, उदा। '{x: स्टेटिक लोकल: कुछ कनवर्टर। इंस्टेंस}'? – itowlson

+0

यह एक बहुत अच्छा सुझाव है। अपने स्वयं के मूल्य कन्वर्टर्स बनाते समय आपको हमेशा प्रॉपर्टी गुणों के बजाय कनवर्टर पैरामीटर स्वीकार करना पसंद करते हैं ताकि आप इस तरह के सिंगलटन इंस्टेंस का उपयोग कर सकें। संसाधनों का उपयोग करने से यह बहुत आसान है। मैं आमतौर पर कुछ ऐसा कहता हूं जैसे {x: स्टेटिक लोकल: इनवर्टेडबोलियन कनवर्टर.डिफॉल्ट} या कुछ। – Josh

+0

@ itowlson - हाँ उदाहरण पर - मैंने अपनी प्रतिक्रिया संपादित की है। पकड़ के लिए Thx। – micahtan

2

मैं इस तरह से अपने बताते हुए कर रहे हैं करने के लिए एक तरीका है पता नहीं है, लेकिन मैं सिर्फ एक नमूना के रूप में इस की कोशिश की और यह काम किया कुछ। अपनी App.xaml.cs फ़ाइल में आप एक विधि बना सकते हैं जो कनवर्टर्स को लोड करने के लिए प्रतिबिंब का उपयोग करती है।

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
    LoadConverters(); 
} 

private void LoadConverters() 
{ 
    foreach(var t in Assembly.GetExecutingAssembly().GetTypes()) 
    { 
     if (t.GetInterfaces().Any(i => i.Name == "IValueConverter")) 
     { 
      Resources.Add(t.Name, Activator.CreateInstance(t)); 
     } 
    } 
} 

तो फिर तुम इस तरह के साथ कनवर्टर का उपयोग कर सकते हैं, आधे रास्ते वहाँ मुझे लगता है।

<Button Width="{Binding Width, Converter={StaticResource TrivialFormatter}}" /> 

दृष्टिकोण आप का प्रस्ताव कर रहे हैं के साथ समस्या यह Xaml पार्सर कब और कैसे अपने कनवर्टर के कई उदाहरणों बनाने के लिए पता नहीं है कि है। इसे संसाधन के रूप में बनाना केवल एक उदाहरण सुनिश्चित करता है।

+0

इसी तरह की थीम पर, आप एक मार्कअप एक्सटेंशन बना सकते हैं जो इसके तर्क प्रकार का उदाहरण देता है। फिर आप 'कनवर्टर = {स्थानीय: InstanceOf {x: स्थानीय टाइप करें: TrivialFormatter}} लिख सकते हैं। जैसा कि आप ध्यान देते हैं, हालांकि, इसके परिणामस्वरूप प्रत्येक बाध्यकारी के लिए एक अलग तत्कालता हो सकती है, जो संभावित रूप से अपर्याप्त है (विशेष रूप से यदि आइटम टेम्पलेट में बड़े आइटम नियंत्रण के लिए उपयोग किया जाता है)। – itowlson

6

तकनीकी तौर पर मैं आप ऐसा कर सकते विश्वास है, लेकिन XAML तुलना द्वारा इतना भयानक है कि यह सादगी और स्पष्टता का स्वर्ग की तरह दृष्टिकोण नज़र "तुच्छ संसाधनों के बहुत सारे" कर देगा है:

<Button Height="50"> 
    <Button.Width> 
    <Binding Path="Width" ElementName="textBox1" UpdateSourceTrigger="PropertyChanged"> 
     <Binding.Converter> 
     <local:TrivialFormatter /> 
     </Binding.Converter> 
    </Binding> 
    </Button.Width> 
</Button> 

मेरे पास है इसका परीक्षण नहीं किया गया क्योंकि पढ़ने यह मेरी आंखों को पानी बनाता है ...

+5

यह भी ऐसा करने का एक बिल्कुल वैध तरीका है। लेकिन जैसा कि आपने देखा है कि एक्सएएमएल की वर्बोजिटी वाचा के सन्दूक की तरह है और केवल इसे देखकर आपकी आत्मा को भस्म कर दिया जाएगा। – Josh

+0

यह दृष्टिकोण उपयोगी हो सकता है यदि आप कनवर्टर के विशिष्ट उदाहरण पर कुछ संपत्ति सेट करना चाहते हैं, जैसे ' ' – chviLadislav

5

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

ऐसा करने के कई कारण हैं जो आप करना चाहते हैं।

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

एक और अच्छा कारण यह है कि मूल्य कन्वर्टर्स में अपवाद नहीं सत्यापन त्रुटियों जो हो सकता है के रूप में माना जाएगा सिल्वरलाइट में बट में एक बड़ा दर्द।भले ही आप बाध्यकारी में मान्य होने के लिए ValidatesOnExceptions सेट करते हैं, यदि आपका मान कनवर्टर अपवाद फेंकता है, तो सिल्वरलाइट इसे प्रचारित करने देगा। यदि आप रूपांतरण करने के लिए ViewModel का उपयोग करते हैं, तो एक अपवाद को सत्यापन त्रुटि के रूप में माना जाएगा।

नकारात्मकता यह है कि आप सामान्य प्रयोजन मूल्य कनवर्टर की "पुन: प्रयोज्यता" में से कुछ खो देते हैं।