2011-04-12 10 views
7

मुझे Setting event handlers inside a Setter.Value structure में वर्णित समस्या का सामना करना पड़ा। लेकिन मैं समझना चाहता हूं कि प्रश्न के लेखक द्वारा प्रदान किया गया समाधान क्यों काम नहीं करता है। ऐसा लगता है कि मैंने कुछ अवधारणा को याद किया।क्यों "एक Setter.Value संरचना के अंदर इवेंट हैंडलर सेट करना" संकलन त्रुटि देता है?

+0

* "प्रश्न के लेखक द्वारा प्रदान किए गए समाधान" * का मतलब है कि यह ऐसे हैंडलर संलग्न करने के लिए काम नहीं करता है, है ना? (बस भ्रम से बचने के लिए क्योंकि मैंने एक "समाधान" प्रदान किया है जिसमें 'EventSetters' का उपयोग करना शामिल है, जो काम करता है) –

+0

हां, आप सही हैं। – alehro

उत्तर

13

यह एक्सएएमएल कोड-पीढ़ी की पीढ़ी में एक बग प्रतीत होता है। XAML फ़ाइलों के लिए उपयोगकर्ता कोड-बैक के अतिरिक्त, एक "कंपाइलर" जेनरेट किया गया संस्करण है जो नामांकित तत्वों (यानी x: नाम) के लिए InitializeComponent और क्लास फ़ील्ड को परिभाषित करता है।

System.Windows.Markup.XamlParseException occurred 
    Message='Set connectionId threw an exception.' Line number '13' and line position '8'. 
    Source=PresentationFramework 
    LineNumber=13 
    LinePosition=8 
    StackTrace: 
     at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri) 
    InnerException: System.InvalidCastException 
     Message=Unable to cast object of type 'System.Windows.Controls.MenuItem' to type 'System.Windows.Controls.Button'. 
     Source=Windows7Theme 
     StackTrace: 
      at Windows7Theme.MainWindow.System.Windows.Markup.IComponentConnector.Connect(Int32 connectionId, Object target) in c:\Users\TJoe\Documents\Visual Studio 10\Projects\Windows7Theme\Windows7Theme\MainWindow.xaml:line 13 
      at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetConnectionId(Object root, Int32 connectionId, Object instance) 
     InnerException: 

उत्पन्न कोड-पीछे फ़ाइलों obj फ़ोल्डर में पाया जा सकता है, तो:

<Window.Resources> 
    <Style TargetType="Button"> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu> 
        <MenuItem Header="Header" Click="MenuItem_Click"/> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<Button /> 

आप इस चलाते हैं, तो आप निम्न अपवाद मिल जाएगा:

एक सरल उदाहरण को देखते हुए हम जांच करता है, तो यह है कि हम निम्न कोड देख सकते हैं:

void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) { 
    switch (connectionId) 
    { 
    case 1: 

    #line 13 "..\..\..\MainWindow.xaml" 
    ((System.Windows.Controls.Button)(target)).AddHandler(System.Windows.Controls.MenuItem.ClickEvent, new System.Windows.RoutedEventHandler(this.MenuItem_Click)); 

    #line default 
    #line hidden 
    return; 
    } 
    this._contentLoaded = true; 
} 

मुद्दा ज ere उत्पन्न कोड MenuItem को Button पर डालने का प्रयास कर रहा है। हम तो जैसे हमारे नमूना बदल हैं:

<Window.Resources> 
    <ContextMenu x:Key="ContextMenuKey"> 
     <MenuItem Header="Header" Click="MenuItem_Click"/> 
    </ContextMenu> 

    <Style TargetType="Button"> 
     <Setter Property="ContextMenu" 
       Value="{StaticResource ContextMenuKey}" /> 
    </Style> 
</Window.Resources> 

<Button /> 

तब उत्पन्न कोड है:

void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) { 
    switch (connectionId) 
    { 
    case 1: 

    #line 10 "..\..\..\MainWindow.xaml" 
    ((System.Windows.Controls.MenuItem)(target)).Click += new System.Windows.RoutedEventHandler(this.MenuItem_Click); 

    #line default 
    #line hidden 
    return; 
    } 
    this._contentLoaded = true; 
} 

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

यदि हमने ग्रिड में बटन को बदलने के लिए बटन बदल दिया है, तो उपर्युक्त अपवाद यह इंगित करेगा कि यह मेनूइटम को ग्रिड में डालने में विफल रहा है। क्योंकि अब ग्रिड मूल तत्व है। यह इंगित करता है कि स्टाइल लक्ष्य के प्रकार से इसका कोई लेना-देना नहीं है।

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

आखिरकार, यह एक्सएएमएल कोड जेनरेटर में एक बग है।

+2

अद्भुत स्पष्टीकरण के लिए धन्यवाद। मुझे लगता है कि आप इस बग को wpf डेवलपर्स में फाइल कर सकते हैं। – alehro

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