由于XAML到.NET代码生成中的错误,此命名空间是否会发生冲突?

Mat*_*art 6 .net c# wpf xaml namespaces

下面我将介绍如何重现我收到的错误.它在VS 2010,2012和2013中表现相同.如下所示,将其分解为多个项目非常重要.

重现错误的步骤:

  1. 创建解决方案.

  2. 创建一个名为Common的C#类库,其中包含一个名为Handler.cs的文件:

    using System;
    
    namespace Common
    {
        public delegate void Handler(object sender, EventArgs args);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建一个名为MyControlLibrary的WPF用户控件库项目,引用Common.在其中,创建一个名为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>
    
    Run Code Online (Sandbox Code Playgroud)

    MyControl.xaml.cs:

    using System.Windows.Controls;
    using Common;
    
    namespace ControlNamespace
    {
        public partial class MyControl : UserControl
        {
            public MyControl()
            {
                InitializeComponent();
            }
    
            public event Handler MyEvent;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建一个名为MyWpfApplication的WPF应用程序项目,引用Common和MyControlLibrary.在其中,创建WindowNamespace.Common.cs以及一个名为MyWindow.xaml的窗口.

    WindowNamespace.Common.cs:

    namespace WindowNamespace.Common
    {
    }
    
    Run Code Online (Sandbox Code Playgroud)

    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>
    
    Run Code Online (Sandbox Code Playgroud)

    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)
            {
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 构建解决方案.

您应该收到以下错误,指向MyWindow.xaml的第7行:

命名空间"WindowNamespace.Common"中不存在类型或命名空间名称"Handler"(您是否缺少程序集引用?)

如果打开为MyWindow.xaml生成的.gics文件,则应在IComponentConnector.Connect方法中看到以下内容:

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

问题的根源是它试图在WindowNamespace中找到Common.Handler.这可以通过将其生成为:

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

或者通过在文件顶部添加一个using:

using Common;

...

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

请注意,如果所有这些源文件都捆绑到一个项目中,则错误消失,因为.gics文件的生成方式不同(即它没有显式地将处理程序添加到事件中).

这实际上是XAML中的一个错误 - > .NET翻译,还是我做错了什么?

Mar*_*man 0

如果您在 MyWpfApplication 中的 WindowNamespace.Common 命名空间声明中重新声明 Handler 委托并尝试编译,则可以了解会发生什么情况:

Error   1   Cannot implicitly convert type 'WindowNamespace.Common.Handler' to 'Common.Handler' c:\Dev\YourSolution\MyWpfApplication\MyWindow.xaml  7   63  MyWpfApplication
Run Code Online (Sandbox Code Playgroud)

Common 项目声明了一个名为“Common”的全局命名空间,您的控件库也在使用该命名空间。但是,当您的应用程序显式声明“WindowNamespace.Common”时,它会创建一个本地命名空间,该命名空间恰好与父控件所在的命名空间相同。这实际上会产生 Visual Studio 文档中针对编译器错误 CS0433描述的歧义问题。

将 MyWpfApplication 中的公共命名空间声明更改为“Common”,问题就会消失。