为什么将二级子类化 Button 控件添加到 Grid 会产生 E_INVALIDARG?

发布于 2025-01-05 20:37:42 字数 1908 浏览 1 评论 0原文

我在处理 C++/CX 中的 Windows.UI.Xaml.Button 类的子类时遇到了这个问题,我想知道发生了什么。

如果我将一个控件实例添加到网格中,一切都会按预期工作。

如果我对控件进行子类化并添加子类的实例,一切都会按预期工作。

但是,如果我对我的子类化控件进行子类化并将其实例添加到网格中,我会在 Grid::Children::Append() 期间抛出 E_INVALIDARG。什么给?

我的代码大致如下(LayoutRoot 是 MainPage.xaml 中的网格,此示例已在空的简单 Metro 应用程序中进行了测试):

// Scenario 1: This works (duh!)
LayoutRoot->Children->Append(ref new Button());

// Scenario 2: This works
LayoutRoot->Children->Append(ref new MyButton1());

// Scenario 3: This doesn't work, it will cause an E_INVALIDARG to be thrown by the collection
LayoutRoot->Children->Append(ref new MyButton2());

// This is how MyButton1 and MyButton2 is defined
public ref class MyButton1 : public Button { 
  public:
    MyButton1() {};
    ~MyButton1() {};
};

public ref class MyButton2 : public MyButton1 { 
  public:
    MyButton2() {};
    ~MyButton2() {};
};

请注意,此问题与 这个问题,但是错误和这个场景完全不同,我可以单独发布这个。

更新: 在阅读 Ian Griffiths 的这篇文章,但我需要了解更多有关这个具体的例子。可以找到重复此问题的完整代码 在这里,请参阅线程中的第 3 篇文章

更新:据我目前所知,并非所有 WinRT 类型都支持继承。我对此没有可靠的源参考,但我读到 Windows.UI.Xaml 类应该支持继承,但其他 WinRT 类型不会。 Windows.UI.Xaml.Controls.Button 类显然可以,而我自己的 MyButton1 则不能。我想知道我必须做什么才能使 MyButton1 像 Button 类一样“可继承”。

我发现用 Windows.UI.Xaml.Controls.ProgressBar 替换 Windows.UI.Xaml.Controls.Button 类将使方案 2 失败,这告诉我 ProgressBar 类(尚)不可能进行子类化。这一观察使我相信一个类需要做一些明确的事情才能使其可继承。

I've come across the this problem dealing with subclasses of the Windows.UI.Xaml.Button class in C++/CX, and I'd like to know what's going on.

If I add a control instance to a grid, everything works as expected.

If I subclass the control and add an instance of the subclass, everything works as expected.

But if I subclass my subclassed control and add an instance of it to the grid I get E_INVALIDARG thrown during Grid::Children::Append(). What gives?

My code looks roughly like this (LayoutRoot is a Grid in MainPage.xaml, this sample has been tested in an empty simple metro application):

// Scenario 1: This works (duh!)
LayoutRoot->Children->Append(ref new Button());

// Scenario 2: This works
LayoutRoot->Children->Append(ref new MyButton1());

// Scenario 3: This doesn't work, it will cause an E_INVALIDARG to be thrown by the collection
LayoutRoot->Children->Append(ref new MyButton2());

// This is how MyButton1 and MyButton2 is defined
public ref class MyButton1 : public Button { 
  public:
    MyButton1() {};
    ~MyButton1() {};
};

public ref class MyButton2 : public MyButton1 { 
  public:
    MyButton2() {};
    ~MyButton2() {};
};

Note that this question is slightly similar to this question, but the error and the scenario is sufficiently different for me to post this one separately.

UPDATE: I think I'm on the right track understanding this problem after reading this article by Ian Griffiths, but I need to know more regarding the behavior of this specific example. Full code to repeat this problem can be found here, see the 3rd post in the thread.

UPDATE: From what I've learned so far, not all WinRT types support inheritance. I have no reliable source references for this, but I've read that the Windows.UI.Xaml classes should support inheritance, but other WinRT types won't. The Windows.UI.Xaml.Controls.Button class obviously does, while my own MyButton1 doesn't. I'd like to know what I'd have to do to make MyButton1 'inheritable' the way the Button class is.

I've found that replacing the Windows.UI.Xaml.Controls.Button class with Windows.UI.Xaml.Controls.ProgressBar will make scenario 2 fail, which tells me that the ProgressBar class isn't (yet) possible to subclass. This observation is what makes me believe that a class need to do something explicit in order for it to be inheritable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文