Why does adding 2nd level subclassed Button contro

2019-02-19 14:57发布

问题:

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.