Problems using this with LayoutAwarePage!

Nov 22, 2012 at 3:48 PM
Edited Nov 22, 2012 at 3:56 PM

I'm hoping you can help me figure out why my binding isn't working with my project.

I am able to create the database and read from it, it even puts the data into my collection like it's supposed too but my main page List control is still empty. I have an idea it's because I must make my Xaml Page

<common:LayoutAwarePage /> Instead of <Page />

I still have the MainPageModelView page and like I said that works fine.

But I'm making it an extension of LayoutAwarePage instead of PropertyChangedCore

I did copy some of the code in PropertyChangedCore with regard to 

 

            /// <summary>
            /// Property changed event
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged;

            /// <summary>
            /// Raises <see cref="PropertyChanged"/> event/>
            /// </summary>
            /// <param name="propertyName">Name of property to raise event for</param>
            protected void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

 

and placed this inside of LayoutAwarePage. But I have a feeling I need to somehow do it the other way around. The main thing is I can't navigate pages of my project without LayoutAwarePage. Do I need to basically combine these two pages into the Database PropertyChangedCore class and use it as my class extension? I'm still learning Xaml and MVVM so this is a bit new to me and any advice is welcome. 

Just in case you want to see the main xaml page with the binding this is it.

 

<common:LayoutAwarePage 
    x:Class="MHManager.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:collections="using:MHManager.Collections"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:MHManager"
    xmlns:common="using:MHManager.Common"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Name="rootPage"
    BorderBrush="{StaticResource ApplicationPageBackgroundThemeBrush}"
    FontFamily="Global User Interface"
    mc:Ignorable="d"
    >

    <common:LayoutAwarePage.TopAppBar>
        <AppBar x:Name="TopAppBar1"
                AutomationProperties.Name="Top App Bar"
                Background="{StaticResource AppPageBackgroundBrush}"
                Padding="10,0,10,0">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50*" />
                    <ColumnDefinition Width="50*" />
                </Grid.ColumnDefinitions>

                <StackPanel x:Name="LeftPanel"
                            Grid.Column="0"
                            HorizontalAlignment="Left"
                            Orientation="Horizontal">
                    <Button x:Name="Add"
                            Click="OnAddClick"
                            Foreground="White"
                            Style="{StaticResource AddAppBarButtonStyle}"
                            Tag="Add" />
                    <Button x:Name="Edit"
                            Style="{StaticResource EditAppBarButtonStyle}"
                            Tag="Edit" />
                    <Button x:Name="Delete"
                            Style="{StaticResource DeleteAppBarButtonStyle}"
                            Tag="Delete" />
                </StackPanel>
                <StackPanel x:Name="RightPanel"
                            Grid.Column="1"
                            HorizontalAlignment="Right"
                            Orientation="Horizontal">
                    <Button x:Name="Help"
                            Style="{StaticResource HelpAppBarButtonStyle}"
                            Tag="Help" />
                </StackPanel>
            </Grid>
        </AppBar>
    </common:LayoutAwarePage.TopAppBar>

    <Grid x:Name="LayoutRoot" Background="{StaticResource AppPageBackgroundBrush}">
        <Grid Background="{StaticResource AppPageBackgroundBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="150" />
                <RowDefinition Height="1" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <!--  logo background image  -->
            <Image Grid.RowSpan="4"
                   Width="670"
                   Height="574"
                   HorizontalAlignment="Left"
                   VerticalAlignment="Bottom"
                   Opacity="0.15"
                   Source="Assets/Logo.png">
                <Image.RenderTransform>
                    <TranslateTransform X="-150" Y="200" />
                </Image.RenderTransform>
            </Image>

            <!--  Header  -->
            <Grid Background="{StaticResource AppPageHeaderBackgroundBrush}">
                <!--  Top accent and logo  -->
                <Grid VerticalAlignment="Top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="32" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <Border Height="6"
                            VerticalAlignment="Top"
                            Background="{StaticResource AppPageBackgroundBrush}"
                            BorderBrush="{StaticResource AppPageAccentLightBrush}"
                            BorderThickness="0,0,0,1" />

                    <Path Grid.Column="1"
                          Width="32"
                          Height="37"
                          Data="M 0,0 L 32,0 L 32,37 L 0,5 Z"
                          Fill="{StaticResource AppPageBackgroundBrush}" />
                    <Path Grid.Column="1"
                          Width="32"
                          Height="37"
                          Data="M 0,5 L 32,37"
                          Stroke="{StaticResource AppPageAccentLightBrush}" />

                    <Border Grid.Column="2"
                            Background="{StaticResource AppPageBackgroundBrush}"
                            BorderBrush="{StaticResource AppPageAccentLightBrush}"
                            BorderThickness="0,0,0,1" />
                    <Image Grid.Column="2"
                           Width="56"
                           Height="12"
                           Margin="2,0,10,0"
                           Source="Assets/DavisoftCompanyLogoLight.png" />
                </Grid>

                <!--  Back button and page titles  -->
                <Grid Style="{StaticResource PageHeaderTitlePanelStyle}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition x:Name="backButtonColumnDefinition" Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <Button x:Name="backButton"
                            IsEnabled="False"
                            Opacity="0"
                            Style="{StaticResource BackButtonStyle}" />
                    <TextBlock Grid.Column="1"
                               Style="{StaticResource PageHeadingTextBlockStyle}"
                               Text="Manufactured Housing Manager" />
                    <TextBlock Grid.Row="1"
                               Grid.Column="1"
                               Style="{StaticResource PageSubHeadingTextBlockStyle}"
                               Text="for Windows 8" />
                    <TextBlock x:Name="StatusBlock"
                               Grid.Row="6"
                               Grid.ColumnSpan="2"
                               Margin="0,0,0,5"
                               Visibility="Collapsed" />
                </Grid>
            </Grid>
            <Rectangle Grid.Row="1"
                       Height="1"
                       Fill="{StaticResource AppPageAccentDarkBrush}" />

            <!--  Horizontal scroll viewer  -->
            <ScrollViewer x:Name="gridScrollViewer"
                          Grid.Row="2"
                          Style="{StaticResource HorizontalScrollViewerStyle}">
                <!-- Sample categories list -->
                <ItemsControl x:Name="rootItemsControl" Margin="120,0,120,0" IsTabStop="False">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ListBox 
                        Name="MainList"
                        HorizontalAlignment="Stretch" 
                        VerticalAlignment="Stretch"
                        Width="500"
                        ItemsSource="{Binding Contacts}"
                        SelectedItem="{Binding Path=SelectedContact, Mode=TwoWay}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock Text="{Binding Path=ContactLastName}" FontSize="14"/>
                                    <TextBlock Text="{Binding Path=ContactFirstName}" FontSize="14"/>
                                    <TextBlock Text="{Binding Path=ContactMiddleInitial}" FontSize="14"/>
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </ItemsControl>                
            </ScrollViewer>

            <!--  Footer  -->
            <Border Grid.Row="3" Style="{StaticResource PageFooterStyle}">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Margin="22,0,0,0"
                               VerticalAlignment="Center"
                               Style="{StaticResource PageBodyTextBlockStyle}"
                               Text="� davisoft 2013, All Rights Reserved" />
                </Grid>
            </Border>

            <VisualStateManager.VisualStateGroups>

                <!--  Visual states reflect the application's view state  -->
                <VisualStateGroup>
                    <VisualState x:Name="FullScreenLandscape" />
                    <VisualState x:Name="Filled" />

                    <!--  The entire page respects the narrower 100-pixel margin convention for portrait  -->
                    <VisualState x:Name="FullScreenPortrait">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButtonColumnDefinition" Storyboard.TargetProperty="Width">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="32" />
                            </ObjectAnimationUsingKeyFrames>

                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="rootItemsControl" Storyboard.TargetProperty="Margin">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="32,0,90,0" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
        </Grid>
    </Grid>

</common:LayoutAwarePage>

Coordinator
Nov 26, 2012 at 8:39 PM

Your XAML looks really strange to me.  I do not think you need to put ListBox inside ItemsControl inside ScrolleViewer.  I think all you need is ListView probably.

Dec 2, 2012 at 4:14 AM
Edited Dec 2, 2012 at 2:43 PM

I got it to work. I really didn't want to use a listbox  I'm using GridView and Buttons. Each contact is a button and when you click the button I want to pull up the contact details. I finally managed to get the data to bind and the database works fine. But I want to be able to pull up the contact info which means I need a method of setting the SelectedContact to the information based on the contact button. Any suggestions? I actually navigate to a second page to add contacts which is working fine by the way.

Like this

In this screenshot you can see the add button when you right click for the appbar.

Finally you can see the data entry screen allowing for you to return.

This is what I ended up using:

            <!--  Flip View for scrolling horizontally  -->
            <FlipView Grid.Row="2">
                <Grid x:Name="grid" Margin="120,0,120,0">
                    <!--  Contacts list  -->

                    <GridView Grid.Row="2"
                              ItemsSource="{Binding Contacts}"
                              SelectionMode="None">
                        <GridView.GroupStyle>
                            <GroupStyle>
                                <GroupStyle.HeaderTemplate>
                                    <DataTemplate>
                                        <TextBlock Foreground="White" />
                                    </DataTemplate>
                                </GroupStyle.HeaderTemplate>
                            </GroupStyle>
                        </GridView.GroupStyle>
                        <GridView.ItemContainerStyle>
                            <Style TargetType="GridViewItem">
                                <Setter Property="Margin" Value="5" />
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="GridViewItem">
                                            <Button Click="OnContactInfoClick" Style="{StaticResource ContactsMediumButtonStyle}" />
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </GridView.ItemContainerStyle>
                        <GridView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid Orientation="Vertical" />
                            </ItemsPanelTemplate>
                        </GridView.ItemsPanel>
                    </GridView>
                </Grid>
            </FlipView>

The original problem I was having was actually getting the database to work since the C# Page was inheriting 

public class MainViewModel : PropertyChangedCore
    {

and mine was inheriting 

public class MainPageViewModel : LayoutAwarePage 
    {

I need LayoutAware to be able to navigate through my Frame. But I also needed PropertyChangedCore to have the database work. My Solution was to take LayoutAware and since it has to inherit Page to be able to navigate I also had it inherit INotifyProperty and copied the contents of PropertyChangedCore into it.

public class LayoutAwarePage : Page, INotifyPropertyChanged
        {
Is there a better way to do this and get both functionality? 

Coordinator
Dec 3, 2012 at 8:39 PM

This is not really a data issue at all.  You can always bind SelectedContact property to SelectedItem in GridView and set multi-select to false.  Then you can add a command to the button that would invoke you view model's method that will in turn navigate.