Forum Xamarin.Forms

Graphical differences between Operating System

KarimFlactionKarimFlaction USMember
edited January 2017 in Xamarin.Forms

Hello,
I'm making an application in Xamarin, but I have a problem. I made my graphical interface cross-platform in C# and I always tested the display on Android. But when I wanted to check that it was attractive on Windows Phone, I tested on an emulator and I saw a lot of bugs.

Android :

Windows Phone :

I know that parameters are different between OS, but how can I do to don't have more this problem ?

Do I have to make the same graphical interface for every OS, then use an interface ?

Thank you !

Karim

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @KarimFlaction

    Without seeing the XAML used to create the layout there's not much anyone can suggest.
    It looks like you're refering to:

    • Parameters button
    • Aux1: horizontal spacing of buttons
    • Aux2:Horiztontal spacing of buttons

    In fact it looks like all three probably are done with a StackLayout where Orientation="Horizontal" but that's a guess.

  • @ClintStLaurent
    Thank you for your answer.

    I give you my code in attached file.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @KarimFlaction

    You built all the UI in C# in the code behind? Why would you do that?

    This is really hard to read through. I'm not going to be able to do this now at 0530hrs. I can try putting this in a solution after work and try to make some sense of it then.

  • I do the UI in C# because it's easier for me.

    It can change something ?

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @KarimFlaction
    I'm not sure about it changing anything... (although it might, I just don't know) but it sure is harder to read and follow. Experienced XAML developers can read the XAML pretty much as if it were English. I read XAML and I see the rendered page in my head. But when its C# nobody is used to reading
    stack3_GridLayout.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) });
    Every line becomes an effort to remember contructorss such as new GridLength(2, GridUnitType.Star) })
    All the objects are defined at the top then used later down the page...
    It just slows down the reading and comprehension of the entire code page and visualizing what it should render as.

    Plus it isn't very standard when it comes to C#/XAML/MVVM application design. Remember that Xamarin XAML is an evolutionary implementation of WPF XAML, which has 10+ years of history behind it. None of those experienced developers build UI in C#. The whole point is to separate UI from code. Building your UI in this 1998 WinForms style of C$ building is just not how things have been done for the last 10+ years of any 'grown up' software development firm or department.

    I've also seen where using the old ways tends to bring along all the old bad habits. It doesn't have to mean those old bad habits come along... Its syntactically legal to build your UI in C#. But I've observed most people that do it don't use modern concepts. They do it as a crutch to quickly move out of WinForms or some equally old paradigm. They don't bother to update their understanding of the foundation concepts of separating UI from code, MVVM, the power of DataTemplates, Converters, Commands and the myriad of modern tools at their disposal.

    Like I said: Its not wrong per sae and it doesn't have to mean 'bad' or 'old-fashioned'. Its just what I've seen alot; maybe because people don't make an effort to break out of their old ways. For example: Your use of global variables. Duplication of controls like your Aux1 and Aux2

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited January 2017

    @KarimFlaction

    I tried to import your code to a new project.
    Problem 1: Without your globalvariable much of the code has no reference
    Problem 2: Your code tries to add a stack4 that doesn't exist in your code.


    So then I decided to take another approach. I thought I'd show you how to do this in XAML. To be honest I'll probably make a couple changes and finish it up nicer as part of my Xamarin tutorial series. Right now its a little quick and dirty because I only spent 30 minutes on it and want to go watch a movie. But for now you can see how easy it can be in XAML. Some good practices about separating responsibilities and code reuse also go a long way to making it cleaner, smaller and far easier to update.

    Let's start with the screen shot of the finished page just so we know what we are making. Its not a perfect recreation of your page because I'm showing you how, not doing it for you.

    Now lets look at the XAML for the page. Notice the page is laid out in only 50 lines, and that includes spaces to make it easy to read, comments and some extraneous markup for demonstration purposes that could have been better placed in the application-scoped Style definitions.

    How is it we can make that page in 50 lines? Because the page is only worried about laying out the page. That's all it should care about. We defined some styles elsewhere that can be used throughout the application, and did those one time. (see this tutorial)
    The point here is the page isn't worried about defining the look of the app. The page just lays out where things belong. It lets someone else worry about the theme of the app.

    The other thing we did was look at the layout and realize that we have repetition in those two Aux Relay controls. Aux1 and Aux1 are clearly meant to be the same type of thing just controlling two different relays. So we treat them as such. We made an AuxView of type ContentView, then put two of them on the page. Later the AuxView and be updated with more properties and methods for controlling a relay. Thus the control of a relay is defined one place, one time and reused. When you need to make a fix you don't have to scrub through lots and lots of duplicate code and hope you fix them all the same. {yuck!} By creating an AuxView control you could add 20 more of them for only 20 lines of markup and not be making 5x20 individual buttons and labels to micromanage. In other words we're trying to work and design in an object-oriented way.

    Take a look at that 50 lines for the page. See how we add two AuxView and set their respective titles of Aux1: and Aux2:

    The XAML for the AuxView

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="RpxOne.AuxView"
                 x:Name="this"
                 BindingContext="{x:Reference this}" 
                 BackgroundColor="White">
        <ContentView.Resources>
            <ResourceDictionary>
                <Style BasedOn="{StaticResource LabelStyleLrg}"
                                       TargetType="Label">
                    <!-- If this is your default everywhere then just make it that way in the App.xaml.
                         Here I'm showing how you can define a base and still override it on each UI element -->
                    <Setter Property="HorizontalOptions" Value="FillAndExpand"/>
                    <Setter Property="HorizontalTextAlignment" Value="Center"/>
                    <Setter Property="VerticalOptions" Value="FillAndExpand"/>
                </Style>
            </ResourceDictionary>
        </ContentView.Resources>
    
        <Grid RowSpacing="2"
              ColumnSpacing="2"
              Margin="5">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="2*"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>
    
            <Label Grid.Row="0" 
                   Grid.Column="0" 
                   Grid.ColumnSpan="4" 
                   BackgroundColor="#ADD8E6"
                   HorizontalTextAlignment="Start"
                   TextColor="Black"
                   Text="{Binding ViewTitle}"/>
                   <!-- Notice we are overriding the values set for all labels on the entire view because this one is the exception to the rule-->
    
            <Label Grid.Row="1" 
                   Grid.Column="0" 
                   Text="ON"/>
            <Label Grid.Row="1" 
                   Grid.Column="1" 
                   Text="OFF"/>
            <BoxView Grid.Row="1" 
                   Grid.Column="2" 
                   BackgroundColor="Gray">
                <!-- Dummy for layout purposes.  Replace with Timer control -->
            </BoxView>
    
            <Label Grid.Row="1" 
                   Grid.Column="3" 
                   Text="AUTOMATIC FUNCTION"/>
    
        </Grid>
    </ContentView>
    

    The C# code behind the page for the bindable properties

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using Xamarin.Forms;
    
    namespace RpxOne
    {
        public partial class AuxView : ContentView
        {
            public AuxView()
            {
                InitializeComponent();
            }
    
            #region ViewTitle (Bindable string)
            public static readonly BindableProperty ViewTitleProperty =
    BindableProperty.Create("ViewTitle", typeof(string), typeof(AuxView), "default");
    
            /// <summary>The title displayed for this AuxView
            /// 
            /// </summary>
            public string ViewTitle
            {
                get { return (string)GetValue(ViewTitleProperty); }
                set { SetValue(ViewTitleProperty, value); }
            }
            #endregion OffText  (Bindable string)
    
        }
    }
    

    XAML for the Page itself

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:rpxOne="clr-namespace:RpxOne;assembly=RpxOne"
                 x:Class="RpxOne.TestPage"
                 BackgroundColor="{StaticResource PageBackgroundColor}">
    
        <StackLayout Orientation="Vertical"
                     Spacing="2"
                     Margin="5,50,5,5">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style BasedOn="{StaticResource LabelStyleLrg}"
                                       TargetType="Label">
                        <!-- If this is your default everywhere then just make it that way in the App.xaml.
                         Here I'm showing how you can define a base and still override it on each UI element -->
                        <Setter Property="HorizontalOptions" Value="FillAndExpand"/>
                        <Setter Property="HorizontalTextAlignment" Value="Center"></Setter>
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>
    
            <StackLayout Orientation="Vertical"
                         BackgroundColor="White">
                <Label Text="GET SYSTEM REPORT"/>
                <Label Text="GET SYSTEM INFO"/>
                <Label Text="SUBSCRIBE TO EVENTS TRIGGERED REPORT"/>
                <Label Text="SUSBSCRIBE TO AUTOMATIC REPORT"/>
    
                <StackLayout Orientation="Horizontal">
                    <Label Text="SET"/>
                    <Label Text="PARAMETERS"></Label>
                    <Label Text="GET"></Label>
                </StackLayout>
            </StackLayout>
    
            <StackLayout Orientation="Vertical"
                         BackgroundColor="White"
                         Margin="0,10,0,0">
                <Label Text="Aux relay Xtender"
                       TextColor="Black"
                       BackgroundColor="White"
                       FontSize="30"/>
                <rpxOne:AuxView ViewTitle="Aux1:"/>
                <rpxOne:AuxView ViewTitle="Aux2:"/>
            </StackLayout>
    
        </StackLayout>
    
    </ContentPage>
    
Sign In or Register to comment.