Search code examples
wpfmvvmblendability

WPF Design Time Data Confusion


Why is it that when I create some design time data for my MVVM View, I have to nest the xmlns twice to access the properties of the property?

Example:

       <d:DesignProperties.DataContext>
            <local:UserListViewModel>
                <local:UserListViewModel.Users xmlns:local="clr-namespace:ChatModule.ViewModels">
                    <local:User Name="Person 1" />
                    <local:User Name="Person 2" />
                    <local:User Name="Person 3" />
                    <local:User Name="Person 4" />
                    <local:User Name="Person 5" />
                    <local:User Name="Person 6" />
                </local:UserListViewModel.Users>
            </local:UserListViewModel>
       </d:DesignProperties.DataContext>

I already have a local property defined in an xmlns of the UserControl. But to access the User struct in my underlying class, I have to define it again within the Users property.

Why is that?

All this works fine... I can see my runtime data which is awesome. I've never done this before, so it's neat to be able to see it. I notice that I frequently get errors that go away when I compile... but come back again any time I change the xaml.

The property 'Name' was not found in type 'User'.
The property 'Name' was not found in type 'User'.
The property 'Name' was not found in type 'User'.
The property 'Name' was not found in type 'User'.
The property 'Name' was not found in type 'User'.
The property 'Name' was not found in type 'User'.

Obviously it works, or else I wouldn't be able to see the runtime data.

I also want to extract this design time data into another xaml class, and reference it within this class so I don't have the actual design time data located within the view itself... merely a reference to another xaml file.

And so I have done so... like this...

<UserListViewModel xmlns="clr-namespace:ChatModule.ViewModels">
    <UserListViewModel.Users xmlns:local="clr-namespace:ChatModule.ViewModels">
        <local:User Name="Person 1" />
        <local:User Name="Person 2" />
        <local:User Name="Person 3" />
        <local:User Name="Person 4" />
        <local:User Name="Person 5" />
        <local:User Name="Person 6" />
    </UserListViewModel.Users>
</UserListViewModel>

However, when I get rid of the codebehind I get the same errors mentioned above(which go away on a build), but also an error that says

Cannot set properties on propety elements. Line 2 Position 6.

This doesn't allow me to build unlike the other errors. Why is this? How do I fix it? I'm still getting used to this design time data stuff.


Solution

  • Okay so after fiddling around with it, as per the comment of mine above, I have figured it out. It apparently works differently than the view xaml, in that I do not need to specify the xmlns:local twice in order to access the properties of the property. I do not know why this is exactly.

    Here's how my code looks now.

    In my main xaml, I have this:

    <Grid Name="LayoutRoot" d:DataContext="{d:DesignData Source=DesignTimeData/UserListViewData.xaml}">
        <ListView ItemsSource="{Binding Users}" ItemTemplate="{StaticResource UserTemplate}"  VerticalContentAlignment="Center" HorizontalContentAlignment="Stretch" Background="#505050" >
        </ListView>
    </Grid>
    

    And in the separate xaml file I have this:

    <local:UserListViewModel xmlns:local="clr-namespace:ChatModule.ViewModels">
        <local:UserListViewModel.Users >
            <local:User Name="Person 1" />
            <local:User Name="Person 2" />
            <local:User Name="Person 3" />
            <local:User Name="Person 4" />
            <local:User Name="Person 5" />
            <local:User Name="Person 6" />
        </local:UserListViewModel.Users>
    </local:UserListViewModel>
    

    I still get the "The property 'Name' was not found..." in the backing xaml file, but no longer in the main xaml file of the view. I find this to be pretty elegant. And in this way... the view still remains COMPLETELY oblivious to the actual ViewModel type... whereas when I had it in the view xaml file like before, it had to know that information, even if it's only at design time.

    Here's it working by the way... this is in Visual Studio's xaml editor.

    enter image description here

    Here's an example of the issue with the errors, that makes it a chore guessing game getting things right. No intellisense and stuff unless I rebuild to clear the errors until I mess up some syntax again. It still works just fine as Design Time Data, so I don't know what's up.

    enter image description here

    http://i.imgur.com/jiVKm.jpg