Класс, полученный из формы, дает ошибку приведения - PullRequest
0 голосов
/ 24 июня 2018

У меня есть класс в проекте UWP, производный от Windows.UI.Xaml.Shapes.Shape:

public class Hex : Windows.UI.Xaml.Shapes.Shape
{
    public Hex()
    {

    }
}

Когда я попытался создать экземпляр нового члена этого класса в mainPage.cs, я получил InvalidCastException следующим образом:

System.InvalidCastException: Specified cast is not valid.
       at Windows.UI.Xaml.Shapes.Shape..ctor()
       at App1.Hex..ctor()
       at App1.MainPage.Button_Click(Object sender, RoutedEventArgs e)

Вот код из mainPage.cs

private void Button_Click(object sender, RoutedEventArgs e)
{
    var h = new Hex();
    h.Width = 20;
}

но не работает ни то, ни другое. Как я понимаю, защищенный конструктор Shape должен быть доступен из производного класса, так что же происходит? То же самое с производным от Windows.UI.Xaml.Frameworkelemnt работает без проблем.

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Я тоже этого не понимаю;это довольно раздражает, но, очевидно, вы не можете получить от Shape, как вы ожидаете (и должны уметь это делать). Вместо этого вы должны наследовать от Path и таким образом добавлять пути.Здесь я приведу другой ответ на SO, который объясняет это лучше, чем дублирует.

Ответ уже на SO

0 голосов
/ 04 июля 2018

Когда я попытался создать новый член этого класса в mainPage.cs Я получаю InvalidCastException следующим образом:

System.InvalidCastException: Specified cast is not valid.
       at Windows.UI.Xaml.Shapes.Shape..ctor()
       at App1.Hex..ctor()
       at App1.MainPage.Button_Click(Object sender, RoutedEventArgs e)

Спасибо за ваш отзыв. Мы полностью понимаем, что это исключение может вызвать путаницу.

Дело в том, что, несмотря на то, что Shape не распечатан, создание пользовательской фигуры таким способом не поддерживается.

Для рисования пользовательских фигур, пожалуйста, используйте существующие типы фигур.

Например, шестигранную форму можно легко создать с помощью многоугольника с 6 вершинами:

<Polygon
    Points="143,75 143,125 100,150 57,125 57,75 100,50"
    Stroke="Blue"                
    Fill="LightBlue" />

Для более сложных фигур клиенты могут использовать класс Path, как описано здесь: https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/shapes#path

При желании вы можете обернуть любую фигуру в пользовательский элемент управления, например, используя UserControl: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.usercontrol

0 голосов
/ 26 июня 2018

TLDR;Это невозможно без серьезной травмы.Но ... ЭТО ВОЗМОЖНО.

Я начал с воспроизведения проблемы, вот трассировка стека, чтобы доказать это:

   at Windows.UI.Xaml.Shapes.Shape..ctor()
   at App1.Hex..ctor()
   at App1.App1_XamlTypeInfo.XamlTypeInfoProvider.Activate_0_Hex()
   at App1.App1_XamlTypeInfo.XamlUserType.ActivateInstance()

Вы можете видеть, что поставщики типов для элементов xaml(App1_XamlTypeInfo) создаются во время выполнения, поэтому вы не можете переопределить эти методы [Factory | Instance Creation | Builder] с помощью настраиваемого кода.

Даже не пытаться создать неявное преобразование в классе Hex втип Shape может это исправить, очевидно, ограничение C # состоит в том, что вы не можете сделать пользовательское неявное преобразование из подкласса в базовый класс, потому что «оно изменяет уже скомпилированный код» или что-то еще: (*

Другой маршрут можетесли бы отдавал предпочтение инкапсуляции по сравнению с наследованием , вам потребуется заново реализовать / открыть класс Shape во всей его красе и манипулировать внутренним экземпляром Shape, однако будет ограничение в том, что вы не можетереализовать интерфейсы IShape и IShape2 из WPF, потому что они помечены как внутренние.

Насколько я могу судить, единственноеоставленный вариант состоит в том, чтобы изменить исходный код WPF и распространить его ... Я понятия не имею, по вопросам лицензирования, связанных с такими вещами.См. https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Shapes/Shape.cs для класса, который вам нужно изменить, или просто включите ваш собственный производный тип (например, Ellipse), и https://referencesource.microsoft.com/#PresentationFramework/PresentationFramework.csproj, чтобы указать, что его довольно легко построить цитата нужна .

Надеюсь, кто-то еще придет и докажет, что я не прав ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...