2011-04-12 26 views
7

Sorunu, tam olarak Setting event handlers inside a Setter.Value structure'da açıklandığı gibi karşı karşıya getirdim. Ancak, sorunun cevabı tarafından sağlanan çözümün neden işe yaramadığını anlamak istiyorum. Bazı kavramları kaçırmış gibi görünüyor.Neden "Setter.Value yapısı içinde olay işleyicileri ayarlama" derleme hatası veriyor?

+0

* "Sorunun yazarı tarafından sağlanan çözüm" * ile sadece bunun gibi işleyicileri eklemek için çalışmadığı anlamına mı geliyor? (Sadece işe yaramazsa "EventSetters" kullanan bir "çözüm" sağladığımdan beri karışıklıktan kaçınmak için) –

+0

Evet, haklısınız. – alehro

cevap

13

Bu, XAML kod arkalığının oluşturulmasında bir hata gibi görünüyor. XAML dosyalarının kullanıcı kodlarına ek olarak, adlandırılmış öğeler için InitializeComponent ve sınıf alanlarını tanımlayan bir "derleyici" üretilen sürümü vardır (yani x: Name). böylece,

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: 

üretilen arka plan kod dosyaları obj klasörde bulunabilir: Bu çalıştırırsanız

<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 /> 

, aşağıdaki özel durum alırsınız:

basit bir örnek göz önüne alındığında Aşağıdaki kodu görebildiğimizi incelersek, aşağıdaki kodu görebiliriz:

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; 
} 
Oluşturulan kod MenuItem'u Button'a göndermeye çalışıyor. böylece gibi bizim örnek değiştiren ise:

<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 /> 

Sonra oluşturulan koddur:

benim testlere göre
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; 
} 

, kod üreteci o "bağlamak gerektiğini her kontrole bir kimlik atar görünür "veya için işleyicileri/destek alanlarını ekleyin. ContextMenu'nun satır içi eklendiği durumda (yani ilk örnek), olay işleyicileri pencerenin içindeki kök öğeye atanır ve kendisinin kimliğini almaz.

Düğmenin bir Kılavuzda içerilmesi için değiştirildiysek, yukarıdaki istisna bunun MenuItem'i bir Kılavuza dönüştüremediğini gösterir. Çünkü şimdi Izgara, kök elementtir. Bu, Stil hedeflerinin türü ile ilgisi olmadığını gösterir.

ContextMenu ayrı bir kaynak olarak eklendiğinde, kod üreticisi düzgün bir şekilde bir ID atar gibi görünmektedir, bu nedenle işleyicilerin düzgün bir şekilde bağlanması mümkündür.

Nihayetinde, bu XAML kod üretecinde bir hatadır.

+2

Harika bir açıklama için teşekkürler. Bu hatayı geliştiricilere WpF'ye yazabileceğinizi düşünüyorum. – alehro

İlgili konular