2009-08-02 17 views
10

में घिरे एनम पर बाध्यकारी मैं कक्षा के एक enum टाइप की गई संपत्ति के लिए एक combobox बाध्यकारी के साथ पागल हो रहा है, जहां enum खुद को उसी कक्षा में घोषित किया जाता है।एक कॉम्बोबॉक्स को एक कक्षा

मैं यहां दिए गए उत्तर का पालन करने की कोशिश कर रहा हूं (wpf combobox binding to enum what i did wrong?) विशेष रूप से मैं सुझाए गए मार्कअप एक्सटेंशन कोड और मिलान करने वाले xaml कोड का उपयोग कर रहा हूं।

मेरे काम कर कोड है:

एक अलग फाइल में Enum को परिभाषित करना।

namespace EnumTest 
{ 
    public enum TestEnum {one, two, three, four }; 
} 

कक्षा Enum का उपयोग करता है (ध्यान दें कि PropertyChanged कोड चीजों को आसान बनाने के हटा दिया गया है): के लिए

namespace EnumTest 
{ 
    public partial class Window1 : Window 
    { 
     Test _oTest = new Test(); 

     public Window1() 
     { 
      InitializeComponent(); 
      cmbBox.DataContext = _oTest; 
     } 
    } 
} 

एक्सटेंशन विधि: वर्ग का उपयोग करता है

namespace EnumTest 
{ 
    public class Test : INotifyPropertyChanged 
    { 
     private TestEnum _MyVar; 
     public TestEnum MyVar { 
      get { return _MyVar; } 
      set 
      { 
       _MyVar = value; 
       OnPropertyChanged("MyVar"); 
      } 
     } 

     public Test() 
     { 
      _MyVar = TestEnum.three; 
     } 
    } 
} 

कार्यक्रम फ़ाइल एनम

namespace EnumTest 
{ 
    [MarkupExtensionReturnType(typeof(object[]))] 
    public class EnumValuesExtension : MarkupExtension 
    { 
     public EnumValuesExtension() 
     { 
     } 

     public EnumValuesExtension(Type enumType) 
     { 
      this.EnumType = enumType; 
     } 

     [ConstructorArgument("enumType")] 
     public Type EnumType { get; set; } 

     public override object ProvideValue(IServiceProvider serviceProvider) 
     { 
      if (this.EnumType == null) 
       throw new ArgumentException("The enum type is not set"); 
      return Enum.GetValues(this.EnumType); 
     } 
    } 
} 
प्रदर्शित करना

और उस डेटा प्रदर्शित किया जाता है XAML कोड:

<Window x:Class="EnumTest.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:w="clr-namespace:EnumTest" 
    Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <ComboBox Name="cmbBox" 
        Height="20" 
        Width="80" 
        ItemsSource="{Binding Source={w:EnumValues EnumType=w:TestEnum}}" 
        SelectedItem="{Binding Path=MyVar}" 
        /> 
    </Grid> 
</Window> 
ऊपर

सभी अच्छे और dandy है, लेकिन मैं पर परिभाषित किया जा रहा से टेस्ट वर्ग भीतर Enum को परिभाषित करने और Enum खाई करने के लिए चाहते हैं वैश्विक कार्यक्षेत्र। इसलिए जैसा:

namespace EnumTest 
{ 
    public class Test : INotifyPropertyChanged 
    { 
     // Declare Enum **INSIDE** the class 
     public enum TestEnum {one, two, three, four }; 
     private TestEnum _MyVar; 
     public TestEnum MyVar { 
      get { return _MyVar; } 
      set 
      { 
       _MyVar = value; 
       OnPropertyChanged("MyVar"); 
      } 
     } 

     public Test() 
     { 
      _MyVar = TestEnum.three; 
     } 
    } 
} 

तो सवाल मैं जा रहा है के रूप में मिलान XAML वाक्य रचना की ओर संकेत करने के लिए भेजा:

 <ComboBox Name="cmbBox" 
        ... 
        ItemsSource="{Binding Source={w:EnumValues EnumType=w:Test+TestEnum}}" 
        ... 
        /> 

लेकिन इस (एक तरह से) मेरे लिए काम नहीं करता। मैं जब मैं एक साफ निर्माण करना एक 2008 वी.एस. स्थिति पट्टी पर संदेश "सफल बनाएँ", लेकिन मैं यह भी एक त्रुटि XAML

Type 'Test+TestEnum' was not found. 

में रिपोर्ट की जा रही लेकिन कोड की उम्मीद रन के रूप में मिलता है!

हालांकि इसका मतलब है कि xaml डिजाइनर लोड नहीं होगा। इसलिए जब तक मैं xaml त्रुटि को साफ़ नहीं कर सकता, तब तक मैं और अधिक wpf काम करने में खराब हूं।

अब मैं सोच रहा हूं कि यह एक वीएस 2008 एसपी 1 मुद्दा है, और मेरे हिस्से पर कोई समस्या नहीं है।

संपादित

  1. मेरी समस्या बयान अधिक स्पष्ट किए गए।
  2. जोएल के 1 समाधान की कोशिश की, लेकिन मैं और 2 XAML त्रुटियों
  3. की कोशिश की जोएल के 2 समाधान चलाते कोड के साथ समाप्त हो गया और कहा कि सीधे बॉक्स से बाहर काम किया - तो मुझे लगता है कि एक के साथ जा रहा हूँ!

नोट्स तो सवाल यह है कि मैं XAML के लिए वाक्य रचना की इस शैली का उपयोग करता है से MarkupExtension कोड मिला:

<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/> 

जब मैं का उपयोग करें कि मैं कह रही है कि एक संकलन त्रुटि मिलती है कोई EnumValues ​​कन्स्ट्रक्टर 1 पैरामीटर लेता है। मैंने कुछ googling किया और यह वीएस में एक त्रुटि प्रतीत होता है। मैं वीएस 2008 एसपी 1 का उपयोग कर रहा हूँ। मैंने कुछ टिप्पणियां देखीं जो वीएस 2010 बीटा में होने वाली थीं। वैसे भी, यही कारण है कि मैं

<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/> 

के xaml वाक्यविन्यास का उपयोग करता हूं क्योंकि यह वाक्यविन्यास काम करता है!

+0

कन्स्ट्रक्टर के बारे में त्रुटि के संबंध में, यह केवल डिजाइनर में होता है।यह अन्यथा ठीक काम करना चाहिए। इस त्रुटि से बचने के लिए, एक अलग असेंबली –

+0

@ थॉमस में मार्कअप एक्सटेंशन को परिभाषित करें: मैं भूल गया था कि डिज़ाइनर किस तरह से/कहां और कैसे इसे तुरंत चालू करता है, उसके बारे में कैंसर के बारे में बता सकता है। –

+0

@ जोएल - और नौसिखिया wpf प्रोग्रामर इस तरह की बात कैसे जानते हैं? निर्माण उपकरण के एक हिस्से को संतुष्ट करने के लिए एक अलग असेंबली में कक्षा को रखने के बारे में जानना असंभव IMHO है। लेकिन जब तक मुझे उचित समझ नहीं मिलती तब तक मैं उस पर नाराज रहूंगा। एक बार फिर धन्यवाद। –

उत्तर

3

डेटा स्रोत के रूप में उपयोग के लिए enum मूल्यों होने का एक और तरीका है:

<Window.Resources> 
    <ObjectDataProvider 
     MethodName="GetValues" 
     ObjectType="{x:Type sys:Enum}" 
     x:Key="TestValues"> 
     <ObjectDataProvider.MethodParameters> 
      <w:Type2 
       TypeName="w:Test+TestEnum" /> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 

... 

ItemsSource="{Binding Source={StaticResource TestValues}}" 

ध्यान दें कि आप अभी भी TypeExtension और नेस्टेड प्रकार के साथ अलौकिकता की वजह से Type2Extension की जरूरत है। लेकिन आपको अतिरिक्त कस्टम मार्कअप एक्सटेंशन की आवश्यकता नहीं होगी। यदि आप कई स्थानों पर सूची का उपयोग करेंगे, तो यह बेहतर होगा, क्योंकि आप इसे अपने App.xaml संसाधनों में घोषित कर सकते हैं।

+0

इसके लिए बहुत बहुत धन्यवाद - यह मुझे बहुत लंबे समय तक बहुत पागल कर रहा है! –

+1

बहुत अच्छा - मैं विधि पैरामीटर में गणना घोषित करने में "+" गायब था, और यह मुझे बोनर चला रहा था। –

1

x:Type मार्कअप एक्सटेंशन का उपयोग करने के बारे में क्या?

{w:EnumValues EnumType={x:Type w:Test+TestEnum}} 

INotifyPropertyChanged को लागू करने के अलावा, मैं अपने कोड वास्तव में कॉपी किया है। मुझे आपको मिली त्रुटियां मिलती हैं, लेकिन ऐसा लगता है कि यह ठीक है। हालांकि, डिजाइनर को लोड करने में सक्षम होने के लिए यह बहुत परेशान है। मैंने कोशिश नहीं की है कि समस्या हल हो गई है।

मुझे एमएसडीएन पर नेस्टेड प्रकारों के बारे में एमएसडीएन पर this page मिला, और उस धागे में एक सुझाव कस्टम MarkupExtension नेस्टेड प्रकार के नाम को हल करने के लिए एक कस्टम था। मैं इसे काम करने की कोशिश कर रहा हूं, लेकिन अब तक कोई भाग्य नहीं है। मुझे कभी-कभी Type2Extension पर समान त्रुटियां मिलती हैं, और मुझे अन्य tweaks के साथ "enum टाइप सेट नहीं है" मिलता है।

आह! मूल लेखक GetType() पर कॉल करने में एक बग था! यहाँ ठीक किया है Type2Extension और मैं इसे कैसे उपयोग कर रहा था:

public class Type2Extension : System.Windows.Markup.TypeExtension { 
    public Type2Extension() { 
    } 

    public Type2Extension(string typeName) { 
     base.TypeName = typeName; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) { 
     IXamlTypeResolver typeResolver = (IXamlTypeResolver) serviceProvider.GetService(typeof(IXamlTypeResolver)); 
     int sepindex = TypeName.IndexOf('+'); 
     if (sepindex < 0) 
      return typeResolver.Resolve(TypeName); 
     else { 
      Type outerType = typeResolver.Resolve(TypeName.Substring(0, sepindex)); 
      return outerType.Assembly.GetType(outerType.FullName + "+" + TypeName.Substring(sepindex + 1)); 
     } 
    } 
} 

और XAML:

ItemsSource="{Binding Source={w:EnumValues {w:Type2 w:Test+TestEnum}}}" 

यह ठीक और डिजाइनर भार काम करने के लिए प्रकट होता है। मैं अपने खुद के छोटे पुस्तकालयों में Type2Extension जोड़ रहा हूं।

संपादित करें: अजीब तरह से पर्याप्त है, अगर मैं EnumValues में बदल:

if (this.EnumType == null) 
    throw new ArgumentException("The enum type is not set"); 

इस के लिए:

if (this.EnumType == null) 
    return null; 

तब उन निर्माता त्रुटियों चले जाओ। वह एक और चीज थी जिसे मैंने बदल दिया था। हालांकि, मैं जल्द ही enum मूल्य प्राप्त करने का एक वैकल्पिक तरीका पोस्ट करने जा रहा हूँ।

+0

यदि आपका मतलब है: आइटमसोर्स = "{बाध्यकारी स्रोत = {w: EnumValues ​​EnumType = {x: टाइप डब्ल्यू: टेस्ट + टेस्टएनम}}}" तब बस एक बड़ा संकलन –

+0

असफल रहा। जवाब देने के बाद, मैंने आपके उदाहरण कोड को फिर से बनाने के लिए एक साथ डालना शुरू कर दिया (बस यह देखने के लिए कि यह काम करता है)। अगर मैं कुछ समझता हूं तो मैं संपादित करूंगा। –

+0

इसके लिए धन्यवाद। मैं अभी इसके साथ परेशान करने के लिए बहुत थक गया हूं लेकिन मैं इसे सुबह में पहली बार देखता हूं। मैं wpf के लिए नया हूं और हुप्स के इस तरह के माध्यम से कूदने के लिए बुनियादी चीजें क्या होनी चाहिए जो मुझे पूरी तरह से परेशान कर रही है। –

संबंधित मुद्दे