在XAML内部创建C#类的实例

5

我有一个用C#编写的工作应用程序,现在想要扩展该应用程序,以允许用户在应用程序窗口内切换查看应用程序和浏览嵌入式Web浏览器。

我还有一个单独的工作Web浏览器,也是用C#编写的。

我刚刚为原始应用程序添加了包括“选项卡”显示在内的功能,其中原始应用程序将显示在第一个选项卡上,嵌入式Web浏览器将显示在第二个选项卡上。

应用程序的“选项卡”显示是使用Visual Studio中的XAML标记创建的。现在,我想将同样由C#编写的Web浏览器实例添加到我在XAML标记中创建的第二个选项卡中。

这将类似于:

<TabControl>
        <TabItem Header="Browser">
            <StackPanel>
                <!-- Call/ instantiate the browser here -->
            </StackPanel>
        </TabItem>
</TabControl>

但我不知道如何在XAML标记内调用/创建浏览器实例...

浏览器是使用C#创建的:

namespace Agent
{
    public partial class Browser : Form
    {
        public Browser()
        {
            ...
        }
    }
}

请问有人能解释一下如何在XAML标记内部创建Browser实例吗?

编辑

好的,我已按照建议编辑了我的XAML标记-现在我有:

<Window ...
  xmlns:Agent="clr-namespace:Agent"
  ...>
    <Grid>
        ...
        <TabControl>
            <TabItem Header="R">
                <StackPanel>
                    ...
                </StackPanel>
            </TabItem>
            <TabItem Header="Browser">
                <Agent:Browser x:Name="Browser" />
            </TabItem>
        </TabControl>
    </Grid>
</Window>

我也更新了Browser.cs类,现在它扩展了UserControl,而不是Form:

public partial class Browser : UserControl{

然而,我在这一行代码上遇到了编译错误:

<Agent:Browser x:Name="Browser" />

这段文字的意思是:

名称“Browser”在名称空间“clr-namespace:Agent”中不存在。

但很显然,Browser确实存在于Agent中,正如我在这里包含的代码所示...事实上,当输入<Agent:Browser x:Name="Browser />时,当我键入:时,Browser是自动完成菜单中出现的选项之一......

我做错了什么?为什么编译器认为Browser不存在于Agent中?


1
你正在将(旧且丑陋,这是我的个人观点)WinForms与优美的WPF混合使用。对于WinForms,你需要使用<WindowsFormsHost />元素。祝你好运,你会需要它的。 - XAMlMAX
我对WPF很陌生,之前也没有使用过WinForms...它们有什么区别?我应该做些什么? - Noble-Surfer
你能否更新你的问题,告诉我们你是如何在XAML中使用源自UC的新浏览器的? - XAMlMAX
嗨,我刚刚更新了我的问题,展示了我尝试按照下面回答中提出的方法如何操作,以及目前这种做法对我来说并不奏效。 - Noble-Surfer
2个回答

5
在XAML中实例化任何对象的关键是确保命名空间已声明。您可以提供任何XML前缀并将其分配给CLR命名空间(ref),它将像using语句一样起作用。例如:
<TabControl xmlns:agent="clr-namespace:Agent">
    <TabItem Header="Browser">
        <StackPanel>
            <agent:Browser/>
        </StackPanel>
    </TabItem>
</TabControl>

注意:您的对象必须扩展UIElement(或其子级之一),才能在XAML树中使用。如果您的控件是WinForms控件,则需要找到等效的XAML控件或将其包装在WindowsFormsHost中(ref)。

WPF vs. WinForms

本节的目的是帮助识别命名空间中的平台代码,以及一些权衡。我两种都使用过,并且可以通过经验说出它们各自的优点和缺点。

  • WinForms类位于System.Windows.Forms命名空间中,可通过引用System.Windows.Forms.dll程序集来使用。
  • WPF类位于System.WindowsSystem.Windows.Controls命名空间中,可通过引用一组DLL来使用。
  • WinForms渲染是即时的。这意味着您正在使用位图,并且需要自己负责清除和重绘(通常可以只调用Invalidate())。如果进行大量的图像位操作,WinForms更容易使用。
  • WPF渲染是声明式的。这意味着更多的工作被卸载到GPU上,您只需告诉它如何绘制内容。您还可以使用GPU渲染着色器进行特殊效果。WPF默认外观更好,但它以使易事变得困难而著称。
  • WinForms更易学习,但默认外观有点过时。
  • WPF围绕数据绑定构建,使UI能够自动响应属性值更新。它还可以完全重新设计样式,尽管这是相当大的工程。
如果您刚开始学习,我建议您先开始WPF的较重学习曲线。这将提供基本理解,可转移到其他平台,如Windows Store应用等。

嘿,感谢你的回答。我尝试了你建议的方法,但是在XAML中我遇到了编译错误,错误信息为:“未定义命名空间前缀'Agent'”。编译错误指向的是<agent:Browser />这一行代码。 - Noble-Surfer
我的Browser类继承自Form,我猜你是在说需要找到等效的XAML控件? - Noble-Surfer
命名空间是区分大小写的,因此请确保大小写正确。是的,从WinForms API扩展Form是行不通的。WPF的等效类是UserControl基类。您真的需要决定要构建哪个平台,并仅使用该平台。 - Berin Loritsch
我现在遇到了一个编译错误,它说:“无法将类型为'Browser'的值添加到类型为'UIElementCollection'的集合或字典中...有什么想法吗?” - Noble-Surfer
我认为如果我想从XAML文件内部使用现有的浏览器(Browser.cs),我需要为我的浏览器类创建/编写XAML(即Browser.xamlBrowser.xaml.cs)。我该如何做到这一点? - Noble-Surfer
显示剩余3条评论

0
首先,您需要将该标签放置在您的UserControl开放标签内,如下所示:
<UserControl x:Class="View.testControl"
    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:Agent="clr-namespace:Agent">  

然后你可以像这样使用它:
<TabControl>
    <TabItem Header="R">
        <StackPanel>
            ...
        </StackPanel>
    </TabItem>
    <TabItem Header="Browser">
        <Agent:Browser x:Name="Browser" />
    </TabItem>
</TabControl>  

编辑
根据您在评论中提供的信息,您需要在WPF项目中创建一个自定义控件。要做到这一点,您需要:

  1. 右键单击您的项目;
  2. 选择添加新项;
  3. 从左列的已安装选项中选择WPF
  4. 从中间列的列表中选择自定义控件

现在,您可以使用xmlns属性在XAML中创建该控件。
这里是来自msdn的一个很好的示例,介绍如何创建自定义控件。


xmlns:Agent="clr-namespace:Agent" 这段代码位于 <Window>...</Window> 标签内,我猜你指的是 UserControl 的开放标签? - Noble-Surfer
我需要在XAML中包含/使用Browser.cs类,类似于我包含/使用命名空间Agent的方式吗? - Noble-Surfer
感谢您对我的回答进行更新 - 我已经拥有了 Browser.cs 类,这是我想在项目的主窗口中嵌入的自定义控件 - 我如何确保我可以从 XML 文件中引用/使用它? 我的项目命名空间是 Agent,因此当我在 XAML 文件中输入 <Agent: 时,我期望自动完成选项列表包括 Browser,但目前并没有……即使 Browser.csAgent 命名空间中定义……如何确保 Browser 在我的主窗口的 XAML 文件中可见/可用? - Noble-Surfer
是的,我看了更新中的链接-谢谢。但似乎这是为了向表单添加控件(即添加按钮或其他东西,以允许您操作表单或其一部分)。我要做的是在我的WPF应用程序中嵌入一个(更或多或少)完全功能的Web浏览器,以便我可以从我的应用程序内向用户显示特定网站,并允许他们与该网站进行交互,就像他们从“正常”的Web浏览器(如Firefox或Chrome)中查看它一样。 - Noble-Surfer
当我在我的XAML文件中添加行 <Agent:Browser x:Name="WebBrowser" /> 时,该行会出现编译错误,错误信息为“无法将类型为'Browser'的值添加到类型为'UIElementCollection'的集合或字典中”。 - Noble-Surfer
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接