如何复制粘贴 WPF 窗口(克隆)并且没有错误

本文关键字:克隆 有错误 窗口 何复制 复制 WPF | 更新日期: 2023-09-27 18:35:45

我正在使用带有WPF和C# 5.0的.Net 4.5.2。我在 WPF 项目中创建了一个窗口。 我想将此窗口复制粘贴到解决方案资源管理器中,制作第二个窗口,并将其重命名为新名称。

当我这样做时,新(复制的)窗口的 InitializeComponent() 方法总是给我一个错误。如何在解决方案资源管理器中干净地复制窗口(及其代码等)?

这个问题在这里得到了部分回答:复制粘贴WPF窗口会出现错误,但是答案并没有解决我的问题。

我的方法(行不通):

  1. 创建一个窗口并将其命名为窗口测试
  2. 在解决方案资源管理器中,选择"Windows测试并复制",然后将其粘贴到同一项目中
  3. 将新复制的窗口重命名为窗口测试副本
  4. 在 WindowTestCopy
  5. 中,将 xaml 中的 x:class 属性更改为 WindowTestCopy 而不是 WindowTest
  6. 在 WindowTestCopy
  7. 中打开隐藏的代码,并将对 WindowTest 的任何引用更改为 WindowTestCopy
  8. 编译

预期:无错误,复制(克隆)操作成功

实际:编译错误"无法访问静态上下文中的非静态方法'初始化组件'"。

我只有一个错误。显然,InitializeComponent() 正在成为一个模棱两可的引用,但我不清楚如何对代码进行手动编辑来解决这个问题。我希望VS或Resharper会自动帮助我解决这个问题。

更新

WindowTest 包含两个我之前没有提到的 userControls。复制/粘贴发生后,由于某种原因,以下 xaml 元素在 WindowTestCopy 中变得格式不正确:

xmlns:userControls....(省略号)xmlns:userControls....(省略号)

通过删除这些,Resharper 确定 userControl 对象缺少 xmlns 引用标记,并询问我是否要自动导入它们。我选择了是。Resharper添加缺少的xmlns引用标签后,我能够编译(所有错误都消失了)。

我没有解释为什么会发生这种情况。在我的重现步骤中,我不编辑 xaml,因此它应该与原始 xaml 相同。这是奇怪的行为,但至少有一个解决方法,如前所述。

如何复制粘贴 WPF 窗口(克隆)并且没有错误

当它发生在我身上时,它是这样的:

  1. 在解决方案资源管理器中复制 xaml。
  2. 在解决方案资源管理器中重命名 xaml。
  3. 重命名 xaml 中的 x:类。
  4. 重命名 xaml.cs 中的类名。
  5. 重命名 xaml.cs 中的构造函数。
  6. 为什么一切都还坏了? <==(你可能在这里)
  7. 意识到下面有秘密的巫毒巫术。
  8. 将 xaml 和 xaml 的内容.cs复制到几个记事本。
  9. 从解决方案资源管理器中删除 xaml。
  10. 在解决方案资源管理器中创建具有所需名称的新 xaml。
  11. 使用两个记事本的确切内容覆盖 xaml 和 xaml.cs。
  12. 错误消失了。

其他人实际上发布然后删除了正确的想法,但简要说明原因。

您遇到的问题是由于同一项目中的类重复造成的......即使在解决方案资源管理器中,您可以轻松地复制/粘贴 WPF 窗体或任何其他类、用户控件类等。 复制时,它将文件名后缀为" - Copy",如果立即编译将失败。 原因是什么? 在类本身中,类名和窗口名是相同的。 因此,在项目中,您有两个类实例,并且希望您解决重复项,这令人窒息。 我在 WPF 开发的早期遇到了完全相同的事情。

因此,既然我已经解释了它失败的原因,那么您需要做的是纠正问题。 我在示例项目中创建了一个名为"FirstWindowSample"的窗口,因此创建了两个文件FirstWindowSample.xaml和FirstWindowSample.xaml.cs。 .cs版本是窗口(或用户控件类,原理完全相同)的代码隐藏。

如果您查看"FirstWindowSample.xaml"代码(可视化设计版本),代码将如下所示...

<Window x:Class="YourProject.FirstWindowSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FirstWindowSample" Height="300" Width="300">
    <Grid>
    </Grid>
</Window>

第一行的通知

   x:Class="YourProject.FirstWindowSample"

您需要更改".FirstWindowSample"到您想要的新表单的任何内容,例如

   x:Class="YourProject.SecondWindowSample"

接下来,切换到 CODE-BEHIND 文件 "FirstWindowSample.xaml.cs"。

namespace YourProject
{
    /// <summary>
    /// Interaction logic for FirstWindowSample.xaml
    /// </summary>
    public partial class FirstWindowSample : Window
    {
        public FirstWindowSample()
        {
            InitializeComponent();
        }
    }
}

这是类名及其相应构造函数的硬引用。 只需更改这些以匹配您期望的新窗口名称(例如示例 SecondWindowSample)

namespace YourProject
{
    /// <summary>
    /// Interaction logic for SecondWindowSample.xaml
    /// </summary>
    public partial class SecondWindowSample : Window
    {
        public SecondWindowSample()
        {
            InitializeComponent();
        }
    }
}

最后,您的项目现在将具有一个完全不同的类名,该类名不会重复并导致编译错误。 你第一次遇到这个,是的...发现起来很痛苦。 一旦你得到它,接下来的 2-3 次是"哦-是"的复习......在那之后,你不假思索地去做了。

此问题已通过删除 xaml 中的所有 xlmns 元素并让锐化器自动将它们重新添加来解决。我对这个解决方案不满意,因为它不合逻辑;但是,它确实解决了编译错误。

我将以更简单的方式向您展示:我遇到了与您相同的问题,发生此错误是因为您复制了第一个表单(或此处的页面),而不是将类和文件重命名为新类,但请查看以下代码:

<Page x:Class="Advocacy_Software.Pages.PageRegisterCustomer"
      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" 
      xmlns:local="clr-namespace:Advocacy_Software.Pages"
      mc:Ignorable="d" 
      d:DesignHeight="800" d:DesignWidth="800"
      Title="PageRegisterCustomer" Background="Lavender">
第一行:Advocacy_Software.Pages.PageRegisterCustomer"也必须更新为

就这样!我希望得到帮助!