locked
Building UI for Store Apps using only C# (No Xaml)

    Question

  • My requirement is to build a library to be used by windows 8.1 store apps. I have to provide a page class(Xaml) as a part of the lib as well.  But it seems I cannot include a .xaml file inside a .dll anymore. However I do not want to share my .xaml code during distribution. Thus I am looking to create a page class for windows 8.1 store apps using C# entirely. I know that this is a bad approach but I have no other choice.

    Basically I tried to create a page in the following manner:

    namespace AuthenticationLib { public Frame myFrame; public class LoginPage:Page { public LoginPage () { myFrame = new Frame(); CreateLoginUI(); BitmapImage statusImageBitmap = new BitmapImage(new Uri(myFrame.BaseUri, imagePath)) Window.Current.Content = myFrame; Window.Current.Activate(); } public void CreateLoginUI () { //this.Frame.Content = new Frame(); myFrame = Window.Current.Content as Frame; if (myFrame == null) { myFrame = new Frame(); Window.Current.Content = myFrame; } //Some UI code written here

    myFrame.Content = grid; } private void CommandInvokedHandler(IUICommand command) { if (command.Label == "Yes") { myFrame.GoBack(); } else //something other processing } } }

    The UI appears fine but I am always getting NullException for myFrame.BaseUri and also the navigation fails throwing System.Runtime.InteropServices.COMException when myFrame.GoBack() is executed. I checked that CanGoBack property is set to true yet it is still unable to navigate.

    Is there some initialization I am missing with respect to Frame.. Any help would be appreciated!!

    Wednesday, July 16, 2014 5:18 AM

All replies

  • From the documentation for BaseUri:

    BaseUri can be set to aid resolution of relative uniform resource identifiers (URIs) for further navigation.

    To get or set the uniform resource identifier (URI) of the Framecontrol, use the Sourceproperty.


    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Wednesday, July 16, 2014 12:12 PM
    Moderator
  • Sorry about that!! Here is the running code:

    This code goes in a class library project as LoginPage.cs:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Media.Imaging;
    using Windows.UI.Xaml.Navigation;
    
    namespace TestClassLib
    {
        public class LoginPage:Page
        {
            private Image            LogoImage;
            private Button           cancelbtn;
            private Grid             grid;
            private ColumnDefinition firstColumn;
            private ColumnDefinition secondColumn;
            private ColumnDefinition thirdColumn;
            private RowDefinition    firstRow;
            private RowDefinition    secondRow;
            private RowDefinition    thirdRow;
            private RowDefinition    lastRow;
            public static Frame myFrame;
                                            
            public LoginPage ()
            {
                myFrame = new Frame();
               
                CreateLoginUI();
    
                grid.Height = Window.Current.Bounds.Height;
                grid.Width = Window.Current.Bounds.Width;
                Window.Current.Content = myFrame;
                Window.Current.Activate();
            }
    
            public void CreateLoginUI ()
            {
    
                myFrame = Window.Current.Content as Frame;
    
                if (myFrame == null)
                {
                    myFrame = new Frame();
                    Window.Current.Content = myFrame;
                }
    
                LogoImage = new Image();
                LogoImage.HorizontalAlignment = HorizontalAlignment.Left;
                LogoImage.Height = 158;
                LogoImage.Width = 263;
                LogoImage.Margin = new Thickness(168, 63, 0, 0);
                LogoImage.VerticalAlignment = VerticalAlignment.Top;
                BitmapImage LogoImageBitmap = new BitmapImage(new Uri(myFrame.BaseUri, "\\images\\Logo.jpg"));
                LogoImage.Source = LogoImageBitmap;
    
                //Creating the Cancel Button
                cancelbtn = new Button();
                cancelbtn.Content = "Back";
                cancelbtn.HorizontalAlignment = HorizontalAlignment.Left;
                cancelbtn.Margin = new Thickness(323, 264, 0, 0);
                cancelbtn.VerticalAlignment = VerticalAlignment.Top;
                cancelbtn.BorderBrush = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 160, 160, 160));
                cancelbtn.Background = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 18, 84, 70));
                cancelbtn.Width = 130;
                cancelbtn.Click += Cancelbtn_Click;
    
                //Creating the grid which acts as the container to place all the UI elements
                grid = new Grid();
                grid.Background = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 255, 255, 217));
    
                // Create column definitions.
                firstColumn = new ColumnDefinition();
                secondColumn = new ColumnDefinition();
                thirdColumn = new ColumnDefinition();
    
                //Specifying the column widths
                firstColumn.Width = new GridLength(1, GridUnitType.Star);
                secondColumn.Width = new GridLength(3, GridUnitType.Star);
                thirdColumn.Width = new GridLength(1, GridUnitType.Star);
    
                // Creating row definitions.
                firstRow = new RowDefinition();
                secondRow = new RowDefinition();
                thirdRow = new RowDefinition();
                lastRow = new RowDefinition();
    
                //Specifying the row heights
                firstRow.Height = new GridLength(21);
                secondRow.Height = new GridLength(172);
                thirdRow.Height = new GridLength(359);
                lastRow.Height = new GridLength(216);
    
                // Attached definitions to grid.
                grid.ColumnDefinitions.Add(firstColumn);
                grid.ColumnDefinitions.Add(secondColumn);
                grid.ColumnDefinitions.Add(thirdColumn);
                grid.RowDefinitions.Add(firstRow);
                grid.RowDefinitions.Add(secondRow);
                grid.RowDefinitions.Add(thirdRow);
                grid.RowDefinitions.Add(lastRow);
    
                grid.Children.Add(LogoImage);
                Grid.SetRow(LogoImage, 1);
                Grid.SetColumn(LogoImage, 2);
    
                //Adding the cancelbtn to the grid
                grid.Children.Add(cancelbtn);
                Grid.SetRow(cancelbtn, 2);
                Grid.SetColumn(cancelbtn, 1);
    
                myFrame.Content = grid;
                // Add the Border as the Content of the Parent Window Object.   
    
            }
    
            public void Cancelbtn_Click(object sender, RoutedEventArgs e)
            {
                myFrame.GoBack();
            }
           
        }
    }
    
        
    

    Insert this code in windows store app project after adding lib reference to show the UI:

    LoginPage lp = new LoginPage();

    Thursday, July 17, 2014 5:34 AM
  • I am unable to set the baseUri as it read only. The documentation says that baseUri is URI for XAML constructed object at XAML Load time. Am I getting null because I am not making the UI using XAML?
    Thursday, July 17, 2014 6:32 AM
  • Hi

    My suggestion is to specify the uri using ms-appx:///imagepath format. So that even if your BaseUri is empty the path of the image will be always be correct and will not have issues.

    BitmapImageLogoImageBitmap = newBitmapImage(newUri("ms-appx:///Assets/Logo.scale-100.png"))

    Regards

                


    Varun Ravindranath Please 'Mark as Answer' if my post answers your question and 'Vote as Helpful' if it helps you.

    Thursday, July 17, 2014 11:14 AM
  • Thanks you!! This solves the BaseUri issue. I am still unable to go back to previous page using myFrame.GoBack(). 
    Thursday, July 17, 2014 11:44 AM