6

When I create a new Window, using the Add Item... dialogue, the Window I create, e.g. NewWindow, does not inherit from Window. It only has the same interface as type Object. An example:

I have the popup window code below. The code only sees the IHavePassword members, and not the rest of the members of `LoginPopup', like its controls.

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

OH, here is the necessary XAML as well:

<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>

The IntelliSense on the property Me lists the members of IHavePassword, e.g:

enter image description here

I would expect to see the controls and base Window members here, not those of the interface. How do I go about fixing this?

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • 1
    Can anyone literate please explain the downvote? The question is painstakingly clear as to what I'm asking. Is this personal or something? – ProfK Oct 24 '16 at 15:34
  • 1
    Just for the record: I did not downvote your question. – haindl Oct 25 '16 at 08:43
  • 1
    Just for the record as well, I never had any suspicion at all that is was you, @haindl. – ProfK Oct 27 '16 at 09:11
  • 1
    Is it project/solution specific problem, or VS installation specific? That is, does creating a fresh project and adding a window reproduce this behavior? Also, I am not able to reproduce it myself. – Grx70 Nov 01 '16 at 07:09

4 Answers4

4

I think you just forgot to surround the class with your namespace:

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

        '...

    End Class
End Namespace
haindl
  • 3,111
  • 2
  • 25
  • 31
  • 1
    No, I didn't forget, and `ApptEase.Client.Prism.Views.LoginPopup` is not a namespace but a type name. I surrounded it with `namespace ApptEase.Client.Prism.Views`, which Visual Studio automagically transforms to `namespace Views`. That is, it removes the root namespace from any `namespace` statements, leaving only the extension to the root, in this case `Views`. – ProfK Oct 24 '16 at 13:53
  • 1
    @ProfK You are absolutely right about the type name. I made a quick copy/paste error and edited my post to correct that. Unfortunately I'm more of a C# developer and my last VB.NET experience dates back quite a few years. In my quick tests a wrong namespace was exactly the cause for your kind of problem but I guess there are more potential causes for this error. Oh well, I think that's the kind of "magic" that comes with VB.NET: If it works, perfect. If it doesn't, good luck. The root cause is of course that VB.NET doesn't inherit `LoginPopup` from `Window`, so it just derives from `Object`. – haindl Oct 24 '16 at 14:12
  • 1
    It does inherit from `Window`,.also behind the bloody scenes. – ProfK Oct 25 '16 at 02:56
  • 1
    @ProfK What do you see if you open the Visual Studio Object Browser and select your `LoginPopup` class? Do you see `Public Class LoginPopup Inherits System.Windows.Window`? What do you see when you expand the "Base Types" node? Do you see `IHavePassword` and `Window`? (You can of course use any other tool like Reflector, ILSpy, JustDecompile, dotPeek or ILDASM as well if you want.) – haindl Oct 25 '16 at 08:54
  • 1
    No, it only inherits from object, but the other parts of the `LoginPopUp` partial class, that are generated behind the scenes, in `obj\Debug\Views`, called `LoginPopup.g.vb`, contains the declaration `Inherits System.Windows.Window`, and the third part, called `LoginPopup.g.i.vb` also contains the same declaration for 'Partial Public Class LoginPopup`. The same is now true for all `Window` based views in the project. Me adding `Partial` to the main class, the one visible in Solution Explorer, makes no difference. I am rewriting in C# first, so I can quickly get a 2 day overdue demo out. – ProfK Oct 26 '16 at 05:21
  • @ProfK That's all very strange... And I just realized in my tests that the `.g.vb` and `.g.i.vb` files keep staying in the `obj` folder even if I delete the `.xaml.vb` including any corresponding `Class` declarations in other `.vb` files and just keep the `x:Class="..."` in the XAML of the window. (I didn't know this tiny detail after many years of using WPF.) There are only two more questions I can ask at the moment: Do you get any warnings in the output of your build? If you do a search in the file system of your project (outside of Visual Studio), do you find any other `Class LoginPopup`? – haindl Oct 27 '16 at 09:35
  • @ProfK Oh, I just noticed that you've edited your question two times and that this strange behavior happens to all newly created windows as well. (Sorry for overlooking that important edit.) So, instead of the questions from my previous comment, my primary question is now: What happens if you just try to override some method of a window in that class, for example `Protected Overrides Sub OnMouseDown(e As MouseButtonEventArgs)`? Do you get a compile error? If it does compile then maybe it could be just an IntelliSense error that could be corrected by a repair of the Visual Studio installation. – haindl Oct 27 '16 at 10:42
  • I'm curious -- could it be because the class is a partial class? And It doesn't know that it's inheriting from "ApptEase.Client.Prism.Views.LoginPopup"? I would try making your code behind inherit from ApptEase.Client.Prism.Views.LoginPopup, the same way that your Xaml does. Thinking that maybe the x:Class is somehow not providing enough information. I see this as neither inheritance or composition, from a purely code behind perspective, which would make it think it is inheriting from Object. That'd be my guess. – Michael A. Allen Oct 31 '16 at 17:37
1

Just to be sure, in your comments you said that LoginPopup is a partial class, but in your code, you do not have the "Partial statement". I am primarily a C# developer, so I am not sure, but shouldn`t it be there "Partial Public LoginPopup"?

Lupu Silviu
  • 1,145
  • 11
  • 23
1

To answer the question being asked.

Add a new "Window..." instead of using "Add Item..." and creating a new generic class. Then add your custom code.

NRiding
  • 301
  • 1
  • 5
  • I do add a Window specifically, and not just a new generic class, whatever that is. "Add Item...->Window" is exactly the same as "Add...->Window". They both add a fully furnished Window. – ProfK Nov 16 '16 at 05:33
  • I get the same behavior when the Namespace does not match what is in the xaml file. Adding a namespace around the LoginPopup class declaration fixed it for me. – NRiding Nov 18 '16 at 00:14
0

First, this has nothing to do with partial classes or inheriting from Window, as suggested in so many comments. The item template for a VB WPF Window takes care of all that properly; we stopped "hand-coding" UI windows and controls very long ago.

Then, I have given up on finding out what caused this, except most likely the project file or VS being dysfunctional. I have created a new VB WPF project, and in this one when I add a new Window, everything is fine, i.e. the inheritance is correct.

ProfK
  • 49,207
  • 121
  • 399
  • 775