2013-12-13 10 views
6

Poniżej opisuję, jak odtworzyć błąd, który otrzymuję. Zachowuje się tak samo w VS 2010, 2012 i 2013. Ważne jest rozbicie go na wiele projektów, co zaznaczę poniżej.Czy to kolizja przestrzeni nazw spowodowana jest błędem w XAML generowania kodu .NET?

Kroki do odtworzenia błędu:

  1. Tworzenie rozwiązania.

  2. Tworzenie biblioteki C# klasy o nazwie Common, zawierający jeden plik o nazwie Handler.cs:

    using System; 
    
    namespace Common 
    { 
        public delegate void Handler(object sender, EventArgs args); 
    } 
    
  3. utworzyć projekt WPF biblioteki kontroli użytkownika o nazwie MyControlLibrary, odwołującego Common. W tym celu utwórz formant użytkownika o nazwie 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. utworzyć projekt WPF Application o nazwie MyWpfApplication, przedstawieniu Common i MyControlLibrary. W tym celu utwórz WindowNamespace.Common.cs, a także okno o nazwie 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. Budowanie rozwiązania.

powinien pojawić się następujący błąd, wskazując na linii 7 z MyWindow.xaml:

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

Jeśli otworzysz plik .gics wygenerowany dla MyWindow.xaml, powinieneś zobaczyć następujące w metoda IComponentConnector.Connect:

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

źródłem problemu jest to, że starają się znaleźć Common.Handler w WindowNamespace. To może być rozwiązany przez które ona generowana jako:

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

lub przez dodanie używając do początku pliku:

using Common; 

... 

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

Zauważ, że jeśli wszystkie te pliki źródłowe są dołączone do jednego projektu, błąd zniknie, ponieważ plik .gics jest generowany inaczej (tzn. nie dodaje bezpośrednio obsługi do zdarzenia).

Czy to rzeczywiście błąd w XAML -> .NET tłumaczenie, czy jest coś, co robię źle?

+0

Dziękujemy za włożenie wysiłku w odtworzenie tego problemu. Szkoda, że ​​nie ma jeszcze żadnych rozwiązań. Wydaje się, że niektóre ** ustawienia clr-namespace: ... **, aby zezwolić ** global: ** w przestrzeni nazw rozwiązałyby problemy. –

Odpowiedz

0

Nie ma pojęcia, co się dzieje, jeśli redeclare delegata Handler w deklaracji przestrzeni nazw WindowNamespace.Common w MyWpfApplication i spróbuj skompilować:

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

Wspólny projekt deklaruje globalną przestrzeń nazw o nazwie „Wspólna” , z której korzysta również biblioteka kontrolna. Ale gdy aplikacja jawnie deklaruje "WindowNamespace.Common", tworzy lokalny obszar nazw, który akurat jest taki sam, jak obszar nadrzędny, w którym znajduje się formant nadrzędny. To skutecznie tworzy problem niejednoznaczności opisany w Visual Studio documentation for Compiler Error CS0433.

Zmień deklarację wspólnej przestrzeni nazw w MyWpfApplication tak, aby była po prostu "wspólna", a problem zniknie.

+0

Masz rację co do natury kolizji przestrzeni nazw, że zakładamy, że Common odnosi się do tego, który istnieje w bieżącym obszarze nazw zamiast do globalnego Common. Jednak dwie przestrzenie nazw o tej samej nazwie są ... wspólne, a C# oferuje mechanizmy rozwiązywania tych konfliktów bez konieczności zmiany nazwy jednego z nich. Te mechanizmy po prostu nie mogą być używane w tym przypadku, ponieważ nie jestem tym, który pisze C#, chyba że XAML ujawnia sposób, aby to zrobić. –

+0

Zakładam, że już rozważyłeś i odrzuciłeś aliasing? Być może będziesz musiał podać więcej szczegółów na temat części, nad którymi masz kontrolę. Tak czy inaczej wątpię, żeby to się liczyło jako błąd kompilatora, używa on przestrzeni nazw, którą mu dajesz. Czy nie możesz powiązać zdarzenia z ICommand lub czymś i rozwiązać kolizję w kodzie? –

+0

Nie jestem pewien, w jaki sposób aliasing może pomóc; czy mógłbyś wyjaśnić? Nie określam typu, który nie może zostać rozwiązany, więc nie mam możliwości podania aliasu przestrzeni nazw. Jest to określone tylko w kodzie wygenerowanym w celu przypisania procedury obsługi zdarzenia na podstawie powiązania zdarzenia XAML. –

Powiązane problemy