Почему новые окна WPF, которые я создаю, не наследуются от Window?

#.net #wpf #interface #wpf-controls #implements

#.net #wpf #интерфейс #wpf-элементы управления #реализует

Вопрос:

Когда я создаю новое окно, используя диалоговое окно Добавить элемент …, окно, которое я создаю, например NewWindow , не наследуется от Window. Он имеет тот же интерфейс, что и type Object . Пример:

У меня есть код всплывающего окна ниже. Код видит только IHavePassword элементы, а не остальные элементы LoginPopup, такие как его элементы управления.

 Public Class LoginPopup
    Implements IHavePassword

    Public ReadOnly Property Password As SecureString Implements IHavePassword.Password
        Get
            'Return Me.PasswordBox.????
        End Get
    End Property

    Public Event PasswordChanged As RoutedEventHandler Implements IHavePassword.PasswordChanged
    Public Sub PassWordChangedHandler(sender As Object, e As EventArgs)
        PasswordChangedEvent(sender, e)
    End Sub

    Public Sub Close() Implements IHavePassword.Close
        Throw New NotImplementedException
    End Sub

End Class
  

О, вот и необходимый XAML:

 <Window x:Class="ApptEase.Client.Prism.Views.LoginPopup"
....
<StackPanel Orientation="Vertical" Margin="0">
    <DockPanel LastChildFill="True">
        <TextBlock Text="{Binding Path=UsernameLabel}" DockPanel.Dock="Left" TextAlignment="Right" Margin="5,9,5,5" MinWidth="70" />
        <TextBox Text="{Binding Path=Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Width="Auto" Margin="5" />
    </DockPanel>
    <DockPanel LastChildFill="True">
        <TextBlock Text="{Binding Path=PasswordLabel}" DockPanel.Dock="Left" TextAlignment="Right" Margin="5" MinWidth="70" />
        <PasswordBox x:Name="PasswordBox" PasswordChanged="PassWordChangedHandler" Width="Auto" Margin="5" />
    </DockPanel>
    <DockPanel LastChildFill="True" Height="59">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="Log in" Command="{Binding Path=LoginCommand}" CommandParameter="{Binding ElementName=This}" Margin="5" Padding="15,10,15,10" />
            <Button Content="Cancel" Command="{Binding Path=CancelCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Margin="5" Padding="15,10,15,10"/>
        </StackPanel>
    </DockPanel>
</StackPanel>
  

IntelliSense в свойстве Me перечисляет элементы IHavePassword , например:

введите описание изображения здесь

Я ожидал бы увидеть здесь элементы управления и базовые Window элементы, а не элементы интерфейса. Как мне это исправить?

Комментарии:

1. Может ли кто-нибудь грамотный, пожалуйста, объяснить отрицательный результат? Вопрос предельно ясен относительно того, что я спрашиваю. Это личное или что-то в этом роде?

2. Просто для справки: я не отклонил ваш вопрос.

3. Также для протокола, у меня никогда не было никаких подозрений, что это был ты, @haindl.

4. Это проблема конкретного проекта / решения или специфичная для установки VS? То есть, воспроизводит ли создание нового проекта и добавление окна это поведение? Кроме того, я не могу воспроизвести это сам.

Ответ №1:

Я думаю, вы просто забыли окружить класс своим пространством имен:

 Namespace ApptEase.Client.Prism.Views
    Public Class LoginPopup
        Implements IHavePassword

        '...

    End Class
End Namespace
  

Комментарии:

1. Нет, я не забыл, и ApptEase.Client.Prism.Views.LoginPopup это не пространство имен, а имя типа. Я окружил его namespace ApptEase.Client.Prism.Views , в который Visual Studio автоматически преобразуется namespace Views . То есть это удаляет корневое пространство имен из любых namespace инструкций, оставляя только расширение для root, в данном случае Views .

2. @ProfK Вы абсолютно правы насчет имени типа. Я допустил ошибку быстрого копирования / вставки и отредактировал свой пост, чтобы исправить это. К сожалению, я больше разработчик C # и мой последний VB.NET опыт насчитывает довольно много лет. В моих быстрых тестах неправильное пространство имен было именно причиной вашей проблемы, но я предполагаю, что есть больше потенциальных причин для этой ошибки. Ну что ж, я думаю, что это своего рода «волшебство», которое приходит с VB.NET : Если это работает, отлично. Если это не так, удачи. Основная причина, конечно, в том, что VB.NET не наследуется LoginPopup от Window , поэтому оно просто происходит от Object .

3. Это наследуется от Window ,.также за кровавыми кулисами.

4. @ProfK Что вы видите, если открываете обозреватель объектов Visual Studio и выбираете свой LoginPopup класс? Вы видите Public Class LoginPopup Inherits System.Windows.Window ? Что вы видите, когда разворачиваете узел «Базовые типы»? Вы видите IHavePassword и Window ? (Вы, конечно, можете использовать любой другой инструмент, такой как Reflector, ILSpy, JustDecompile, dotPeek или ILDASM, если хотите.)

5. Нет, оно наследуется только от object, но другие части LoginPopUp частичного класса, которые генерируются за кулисами, в objDebugViews , called LoginPopup.g.vb , содержат объявление Inherits System.Windows.Window , а третья часть, called LoginPopup.g.i.vb , также содержит то же объявление для представлений на основе «Частичного открытого класса LoginPopup . The same is now true for all Window» в проекте. То, что я добавляю Partial к основному классу, который виден в Solution Explorer, не имеет никакого значения. Сначала я переписываю на C #, чтобы быстро выпустить демо-версию, просроченную на 2 дня.

Ответ №2:

На всякий случай, в своих комментариях вы сказали, что LoginPopup является частичным классом, но в вашем коде у вас нет «частичного оператора». Я в первую очередь разработчик C #, поэтому я не уверен, но разве там не должно быть «Частичное общедоступное открытие входа»?

Комментарии:

1. VB voodoo позаботится об этом.

Ответ №3:

Чтобы ответить на заданный вопрос.

Добавьте новое «Window …» вместо использования «Add Item …» и создания нового универсального класса. Затем добавьте свой пользовательский код.

Комментарии:

1. Я добавляю специально Window, а не просто новый универсальный класс, что бы это ни было. «Добавить элемент …-> Window» — это точно то же самое, что «Добавить …-> Window». Они оба добавляют полностью оформленное окно.

2. Я получаю такое же поведение, когда пространство имен не соответствует тому, что находится в файле xaml. Добавление пространства имен вокруг объявления класса LoginPopup исправило это для меня.

Ответ №4:

Во-первых, это не имеет ничего общего с частичными классами или наследованием от Window , как предлагается во многих комментариях. Шаблон элемента для окна VB WPF должным образом заботится обо всем этом; мы прекратили «ручное кодирование» окон пользовательского интерфейса и элементов управления очень давно.

Затем я отказался от попыток выяснить, что вызвало это, за исключением, скорее всего, того, что файл проекта или VS не функционируют. Я создал новый проект VB WPF, и в этом, когда я добавляю новый Window , все в порядке, т. Е. наследование правильное.