2013-12-13 8 views
6

Im Folgenden beschreibe ich, wie ich einen Fehler reproduzieren kann, den ich erhalte. Es verhält sich in VS 2010, 2012 und 2013 genauso. Es ist wichtig, es in mehrere Projekte zu unterteilen, wie ich unten andeute.Tritt diese Namespace-Kollision aufgrund eines Fehlers in der XAML-zu-.NET-Codegenerierung auf?

Schritte, den Fehler zu reproduzieren:

  1. eine Lösung erstellen.

  2. erstellen # Klassenbibliothek C Deutsche genannt, enthält eine Datei namens Handler.cs:

    using System; 
    
    namespace Common 
    { 
        public delegate void Handler(object sender, EventArgs args); 
    } 
    
  3. ein Projekt Benutzersteuer Bibliothek WPF erstellen MyControlLibrary genannt, verweisen Common. Erstellen Sie in diesem ein Benutzersteuerelement mit Name MyControl.xaml.

    MyControl.xaml:

    <UserControl x:Class="ControlNamespace.MyControl" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        mc:Ignorable="d" 
        d:DesignHeight="300" d:DesignWidth="300"> 
        <Grid> 
    
        </Grid> 
    </UserControl> 
    

    MyControl.xaml.cs:

    using System.Windows.Controls; 
    using Common; 
    
    namespace ControlNamespace 
    { 
        public partial class MyControl : UserControl 
        { 
         public MyControl() 
         { 
          InitializeComponent(); 
         } 
    
         public event Handler MyEvent; 
        } 
    } 
    
  4. eine WPF-Anwendungsprojekt namens MyWpfApplication Erstellen, gemeinsame und MyControlLibrary verweisen. Erstellen Sie in diesem Fenster WindowNamespace.Common.cs sowie ein Fenster namens MyWindow.xaml.

    WindowNamespace.Common.cs:

    namespace WindowNamespace.Common 
    { 
    } 
    

    MyWindow.xaml:

    <Window x:Class="WindowNamespace.MyWindow" 
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:c="clr-namespace:ControlNamespace;assembly=WpfControlLibrary1" 
         Title="MyWindow" Height="300" Width="300"> 
        <Grid> 
         <c:MyControl MyEvent="MyControl_MyEvent" /> 
        </Grid> 
    </Window> 
    

    MyWindow.xaml.cs:

    using System; 
    using System.Windows; 
    
    namespace WindowNamespace 
    { 
        public partial class MyWindow : Window 
        { 
         public MyWindow() 
         { 
          InitializeComponent(); 
         } 
    
         void MyControl_MyEvent(object sender, EventArgs args) 
         { 
         } 
        } 
    } 
    
  5. die Lösung erstellen.

Sie sollten die folgende Fehlermeldung, zeigt 7 von MyWindow.xaml der Leitung:

The type or namespace name 'Handler' does not exist in the namespace 'WindowNamespace.Common' (are you missing an assembly reference?)

Wenn Sie die Datei .gics für MyWindow.xaml erzeugt öffnen, sollten Sie sehen die folgenden in die IComponentConnector.Connect Methode:

#line 7 "..\..\MyWindow.xaml" 
((ControlNamespace.MyControl)(target)).MyEvent += new Common.Handler(this.MyControl_MyEvent); 

die Ursache des Problems ist, dass es versucht, Common.Handler in WindowNamespace zu finden. Dies könnte durch die gelöst werden nachdem es erzeugt wird, wie:

#line 7 "..\..\MyWindow.xaml" 
((ControlNamespace.MyControl)(target)).MyEvent += new global::Common.Handler(this.MyControl_MyEvent); 

oder durch Verwendung eines auf den Anfang der Datei hinzufügen:

using Common; 

... 

#line 7 "..\..\MyWindow.xaml" 
((ControlNamespace.MyControl)(target)).MyEvent += new Handler(this.MyControl_MyEvent); 

Beachten Sie, dass, wenn alle diese Quelldateien in einem einzigen Projekt gebündelt werden, Der Fehler verschwindet, da die .gics-Datei anders generiert wird (dh der Handler wird dem Ereignis nicht explizit hinzugefügt).

Ist das tatsächlich ein Fehler in der XAML -> .NET-Übersetzung, oder mache ich etwas falsch?

+0

Vielen Dank für die Mühe, dieses Problem zu reproduzieren. Schade, es gibt noch keine Lösungen. Es scheint, dass einige ** clr-namespace: ... ** Anpassung ** ** global: ** im Namespace würde Probleme beheben. –

Antwort

0

Es gibt einen Hinweis darauf, was passiert, wenn Sie die Handler delegieren in Ihrer WindowNamespace.Common Namespace-Deklaration in MyWpfApplication neu deklarieren und versuchen, zu kompilieren:

Error 1 Cannot implicitly convert type 'WindowNamespace.Common.Handler' to 'Common.Handler' c:\Dev\YourSolution\MyWpfApplication\MyWindow.xaml 7 63 MyWpfApplication 

Das gemeinsame Projekt ist eine globale Namespace deklariert „Common“ genannt , die auch von Ihrer Kontrollbibliothek verwendet wird. Wenn Ihre Anwendung jedoch explizit "WindowNamespace.Common" deklariert, wird ein lokaler Namespace erstellt, der zufällig derselbe Namespace ist, in dem sich das übergeordnete Steuerelement befindet. Dadurch wird das in Visual Studio documentation for Compiler Error CS0433 beschriebene Mehrdeutigkeitsproblem effektiv erstellt.

Ändern Sie Ihre gemeinsame Namespace-Deklaration in MyWpfApplication zu "Common" und das Problem wird verschwinden.

+0

Sie haben die Art der Namespace-Kollision richtig erkannt. Sie geht davon aus, dass Common sich auf die im aktuellen Namespace vorhandene verweist und nicht auf die globale Common. Zwei Namespaces, die denselben Namen verwenden, sind jedoch ... häufig, und C# bietet Mechanismen zum Auflösen dieser Konflikte, ohne eine davon umbenennen zu müssen. Diese Mechanismen können in diesem Fall einfach nicht verwendet werden, da ich nicht derjenige bin, der die C# schreibt, es sei denn, XAML macht einen Weg, dies zu tun. –

+0

Ich nehme an, Sie haben bereits Aliasing berücksichtigt und abgelehnt? Möglicherweise müssen Sie dann genauer angeben, auf welchen Teilen Sie die Kontrolle haben. In beiden Fällen bezweifle ich, dass dies ein Compiler-Fehler ist, es verwendet den Namespace, den Sie ihm geben. Können Sie das Ereignis nicht an einen ICommand oder etwas binden und die Kollision im Code auflösen? –

+0

Ich bin unklar, wie Aliasing hier helfen könnte; Könntest du das klären? Ich gebe den Typ nicht an, der nicht aufgelöst werden kann. Daher habe ich keine Möglichkeit, einen Namespace-Alias ​​bereitzustellen. Dies ist nur in dem Code angegeben, der generiert wird, um den Ereignishandler basierend auf der XAML-Ereignisbindung zuzuweisen. –

Verwandte Themen