vendredi 16 février 2018

Return of development expirence on using XAMARIN for Tizen TV [XAML,C#,TIZEN]

My return of Experience on the 16th of February 2018
Long story short: I have been playing around for a while now with Xamarin for Tizen TV, and this will be great for us XAML/.NET developer when:

  1. It is fully finished and compatible with Tizen TV,  Tizen 4 Tv are released to the public
  2. that the emulator really works correctly
  3. the debugger from Visual Studio actually works.
  4. You can create custom controls to make beautiful UI


Let me explain what I mean:
  • After having played with the framework and after feed back from Samsung and having spoken with a developer from the Xamarin porting team from Samsung, as of today Xamarin for Tizen is more in beta IMO then in release even thought the road map says that it is finished:
 The framework is usable but from what I am told 2018 will allow Samsung to finish developing/debug and see who is interested in using Xamarin for Tizen TV.
  • The Visual Studio Debugger is not working as it should, for example if you set a break point and launch the application on the emulator for Tizen TV I would be hit by one of the following issues either the app will crash, visual studio will crash or when you do hit the break point you will not be able to see the value in you objects using quick watch. (When using the same code FORMS code for UWP, Android or IOS the debugger worked perfectly)
As you can see here:

  • Another issue that Samsung has informed me is that the Emulator for Tizen 4 Tv, is not the best way to develop for their TVs they very strongly recommend that you buy a Tizen 4 TV, the Tv will be updated with the latest firmware and OS.  The emulator doesn't have the same performance as a TV
  • Currently Rendering custom controls on Tizen with Xamrin is not working which can also be issue as you can imagine.

All in all Samsung has a little way to go to finish the Tizen APIs for Xamarin and to finish polishing their code before we (developers) can start building awesome Tizen TV application =).  From what I am told the Xamarin porting team at Samsung are working at 100% to fix everything and I am sure that within a few months everything will be finished.






.

lundi 5 février 2018

Reactive UI with your UWP applications Example II (using your ViewModel) [XAML,C#,RxUI]

In the previous example we saw how to us Reactive UI on a auto complet, in this example we will see another example of how to Reactive UI on a ViewModel in your UWP application.

Here we will connect an property to a Service and a SelectedItem using ReactiveCommand.

First we will create a small class:

    public class MyItem
    {
        public int id { get; set; }
        public string name { get; set; }
    }


Next we will create a small service:

    
    public class MyItemService
    {
        public IObservable<IEnumerable<MyItem>> GetUpcomingItems(int index)
        {
            //get your items here
            //do your http call here
            return null;
        }
    }


Here is my ViewModel:


    public class MainViewModel : ViewModelBase
    {
        //My item loader
        public ReactiveCommand<int, IEnumerable<MyItem>> LoadMyItems
        {
            get;
        }

        //my selected item
        MyItem m_selectedItem;
        public MyItem MySelectedItem
        {
            get { return m_selectedItem; }
            set { RaisePropertyChanged("MySelectedItem"); }
        }

        //my service
        private MyItemService myItemService;

        public MainViewModel()
        {
            //init the serivce
            myItemService = new MyItemService();

            //getting items using the CreateFromObservable
            LoadMyItems = ReactiveCommand
                .CreateFromObservable((int index) =>
                    myItemService.GetUpcomingItems(index));

            //when the vm is activated bind the properties
            this.WhenActivated((CompositeDisposable disposables) =>
            {
                //init
                SelectedItem = null;

                //when SelectedItem has a value go to page
                this
                    .WhenAnyValue(x => x.SelectedItem)
                    .Where(x => x != null)
                    .Subscribe(x => LoadSelectedPage(x))
                    .DisposeWith(disposables);          
            });
        }


        public void LoadSelectedPage(MyItem item)
        {
            //load this page
        }
    }

The interesting part are the loading of the items using ReactiveCommand.CreateFromObservable this will start the loading once this property is binded to a ListView or GridView.

Next the SelectedItem and the this.WhenAnyValue(x => x.SelectedItem) will allow me to navigate or perform an action when this property has a value.

As you can see, Reactive UI  allows us to bind events in the ViewModel, of course you could have used ICommand or RelayCommand but I find Reactive UI to be a much more elegant solution!

Happy coding!






mercredi 6 décembre 2017

Reactive UI with your UWP applications [XAML,C#,RxUI]

In the tutorial we will create a sample application that uses ReactiveUI in a UWP application. what we will do is have a text field, and whenever the user types something into it, you want to make a network request which searches for that query. In bonus we will add a back off to wait for the user to stop typing before doing the request.

The idea is not mine but taken from the ReactiveUI.


First create your UWP application and add the ReactiveUI nuget package:

Either by using the command line:

Or in the Nuget package Manager:

Once installed let the fun begin!

Because we want to do a search we will have to bind a property to the textblock, first in the ViewModel of the page we will add:
        private string _searchValue;
         
        public string SearchValue
        {
            get { return _searchValue; }
            set { Set(ref _searchValue, value); }
        }

Next in the XAML page we will add the SearchValue property to the AutoSuggestBox control as follow:
<AutoSuggestBox
                x:Name="SearchBoxSuggestions"
                Grid.Row="0"                
                PlaceholderText="{Binding Path=[txt_SearchPlaceHolder], Source={StaticResource LocalizedStrings}, FallbackValue='txt_SearchPlaceHolder'}"
                QueryIcon="Find"
                Text="{Binding SearchValue, Mode=TwoWay}" />


In our ViewModel we will need to setup the ReactiveUI events:
 public void SetupRxUI()
 {
               this.WhenAnyValue(x => x.SearchValue)
                    .Where(x => x != null && x.Length >= 3)                   
                   .Subscribe(o => OnSearchCommand());
 }

This means that when the SearchValue property changes and that it is not null and have more then 2 chars we will launch the OnSearchCommand() method.
public void OnSearchCommand()
{
   //do a search
}

We can even imagine that the search command should not be fired every time but only once the user has stopped typing for 700 milliseconds and we would have something like this:

 public void SetupRxUI()
 {
            var Interval = TimeSpan.FromMilliseconds(700);          

            this.WhenAnyValue(x => x.SearchValue)
                    .Where(x => x != null && x.Length >= 3)
                   .Throttle(Interval, RxApp.MainThreadScheduler)
                   .Subscribe(o => OnSearchCommand());
 }

and there you have it!

//Happy Coding

jeudi 30 novembre 2017

Building your Shell for your UWP app, quick tutorial on how to get started [XAML,C#]

In this tutorial we will see how to setup your shell in your UWP application using the UWP Community Toolkit HamburgerMenu control.  I really liked the shell that was done for the sample app of the UWP Community Toolkit and thus we will try to do the same thing!

The HamburgerMenu control in the UWP Community Toolkit sample has an ineteresting way or using narrow and wide states.  It allow us to have a hamburger menu when the app is in narrow mode or have the navigation at the top when we are in the wide mode, this is what we are going to reproduce.

This is when you are in wide mode:



This is when you are in Narrow mode:



And that is what we are going to setup in this tutorial!

Lets start, first we need create a page called Shell.xaml/.cs this will be our shell of our application. 

Next we will create a HamburgerMenu control that we will named x:Name="HamburgerMenu" inside the HamburgerMenu tag we will add a VisualStateManager which will allow us to change between the Narrow and Wide States of the app.  Depending on which state we are in we will need to change the style and the ItemTample of the HamburgerMenu.

 <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="WindowStates">
                <VisualState x:Name="NarrowState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="HamburgerMenu.Style" Value="{StaticResource VerticalHamburgerMenu}" />
                        <Setter Target="HamburgerMenu.ItemTemplate" Value="{StaticResource VerticalItemTemplate}" />

                        <Setter Target="HamburgerMenu.IsPaneOpen" Value="False" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="WideState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="700" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="HamburgerMenu.Style" Value="{StaticResource HorizontalHamburgerMenu}" />
                        <Setter Target="HamburgerMenu.ItemTemplate" Value="{StaticResource HorizontalItemTemplate}" />

                        <Setter Target="HamburgerMenu.PaneBackground" Value="White" />
                        <Setter Target="HamburgerMenu.PaneForeground" Value="Black" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>


For this page we will add 2 DataTemplates :

 <Page.Resources>
        <DataTemplate x:Key="HorizontalItemTemplate" x:DataType="local:SampleCategory">
            <Grid>
                <TextBlock
                    Grid.Column="1"
                    VerticalAlignment="Center"
                    FontFamily="Segoe UI"
                    FontSize="15px"
                    FontWeight="Normal"
                    Foreground="Black"
                    Text="{x:Bind Name}" />
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="VerticalItemTemplate" x:DataType="local:SampleCategory">
            <Grid>
                <TextBlock
                    Padding="30,14"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Top"
                    FontFamily="Segoe UI"
                    FontSize="20px"
                    FontWeight="SemiBold"
                    Foreground="White"
                    Opacity="0.8"
                    Text="{x:Bind Name}" />
            </Grid>
        </DataTemplate>
    </Page.Resources>

Next we will need to set the different styles for the HamburgerMenu which you can find here, most of these style were taken from the sample UWP app of the toolkit and reworked to fit our needs you can check it out here.


In our Shell.xaml.cs file we will add 3 properties:

 public static Shell Current { get; private set; }
So that we can acces the shell from anywhere in the application.

private NavViewModel _currentSample;
So that we know under which tab we arer navigating

private List<NavViewModel> NavigationViews { get; set; }
To load the different view that should be accessible in the nav bar.


Next we need to work on the OnNavigatedTo method, here we are going to want to populate our NavigationViews property and bind it to our HamburgerMenu as follows:

        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            NavigationFrame.Navigating += NavigationFrame_Navigating;

            NavigationViews = new List<NavViewModel>();

            NavigationViews.Add(new NavViewModel() { Name = "Red view", PageView = "RedView" });
            NavigationViews.Add(new NavViewModel() { Name = "Blue view", PageView = "BlueView" });
            NavigationViews.Add(new NavViewModel() { Name = "Orange view", PageView = "OrangeView" });

            HamburgerMenu.ItemsSource = NavigationViews;

            NavigationFrame.Navigate(typeof(BlueView));
        }


You should have something like this in the end:

        public static Shell Current { get; private set; }
        private NavViewModel _currentSample;
        private List<NavViewModel> NavigationViews { get; set; }


        public Shell()
        {
            this.InitializeComponent();
            Current = this;
        }

        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            NavigationFrame.Navigating += NavigationFrame_Navigating;

            NavigationViews = new List<NavViewModel>();

            NavigationViews.Add(new NavViewModel() { Name = "Red view", PageView = "RedView" });
            NavigationViews.Add(new NavViewModel() { Name = "Blue view", PageView = "BlueView" });
            NavigationViews.Add(new NavViewModel() { Name = "Orange view", PageView = "OrangeView" });

            HamburgerMenu.ItemsSource = NavigationViews;

            NavigationFrame.Navigate(typeof(BlueView));
        }


Next we will what to handle the NavigationFrame_Navigating this will allow us to make sure that the correct tab is selected deepending on which tab we click, tap, etc

        private async void NavigationFrame_Navigating(object sender, NavigatingCancelEventArgs navigationEventArgs)
        {
            if (navigationEventArgs.Parameter != null && NavigationViews != null)
            {
                _currentSample = NavigationViews.Where(a => a.Name == navigationEventArgs.Parameter).FirstOrDefault();
            }
            else
            {
                _currentSample = null;
            }

            await SetHamburgerMenuSelection();
        }



        private async Task SetHamburgerMenuSelection()
        {
            if (_currentSample != null)
            {
                if (HamburgerMenu.Items.Contains(_currentSample))
                {
                    HamburgerMenu.SelectedItem = _currentSample;
                    HamburgerMenu.SelectedOptionsItem = null;
                }
            }
            else
            {
                try
                {
                    HamburgerMenu.SelectedItem = null;
                    HamburgerMenu.SelectedOptionsIndex = 0;
                }
                catch (Exception e)
                {
                    //fail in silence
                }
            }
        }

and there you have it =), have fun paying around with the demo app.

Happy coding!

Full Source code of the app here.


mercredi 11 octobre 2017

Allowing a Horizontal list to have a Slidable items [XAML,UWP]

For a hackathon I needed to have items that where slideable when they where in a Horizontal list.
To do this I decided to use the UWP Community Toolkit and rework the SlidableListItem control.

To speed things up we will need to use the Animations from the UWP Community toolkit, install it by using package manager:



Now you should be able to use this namespace :

using Microsoft.Toolkit.Uwp.UI.Animations;

Next lets have a look at the SlidableItem from the UWP toolkit.  You can see that it has a slidable mechanism from left to right and right to left, and that it uses animation to transition from on state to another.

I converted this control so that it would work for my needs, basically all I did was replace these with a mechanism from top to bottom and left to top.  Also all of the animations where changed from the X axis to the Y axis and I had to rework how the animations worked.

You can see the changes here on the Github page, I wont go over them as there isnt any added value for me to do this.

In the demo app, you will see a horizontal list with items in it:
When you swipe down in this sample you will see a red background with the wording delete (you can customise this as you wish) :
When you swipe up you will see another possible action:
To customize your DataTemplate have a look at the one in the sample app:


 <DataTemplate x:Key="KeyQueueSwipeTemplate">
                <local:SlidableGridItem
                    MinWidth="300"
                    MaxWidth="300"
                    HorizontalAlignment="Stretch"
                    ActivationWidth="71"
                    AllowDrop="True"
                    BottomBackground="SkyBlue"
                    BottomCommand="{Binding DataContext.CallBottomItemCommand, RelativeSource={RelativeSource TemplatedParent}}"
                    BottomForeground="White"
                    BottomIcon="Play"
                    BottomLabel="Next"
                    CanDrag="True"
                    DataContext="{Binding DataContext, ElementName=Page, Mode=OneWay}"
                    IsBottomCommandEnabled="True"
                    IsOffsetLimited="False"
                    IsPointerReleasedOnSwipingHandled="True"
                    IsTopCommandEnabled="True"
                    MouseSlidingEnabled="True"
                    TopBackground="OrangeRed"
                    TopCommand="{Binding DataContext.CallTopActionItemCommand, RelativeSource={RelativeSource TemplatedParent}}"
                    TopForeground="White"
                    TopIcon="Delete"
                    TopLabel="Delete">
                    <Grid Height="190" Background="LightGray">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <slidableitemsample:MyUserControl
                            Grid.Column="0"
                            Margin="0,0,0,0"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"
                            AllowDrop="True"
                            CanDrag="True"
                            DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}" />
                    </Grid>
                </local:SlidableGridItem>
            </DataTemplate>


As you can see the most important parts are:
  • BottomBackground="SkyBlue"
  • BottomCommand="{Binding DataContext.CallBottomItemCommand, RelativeSource={RelativeSource TemplatedParent}}"
  • BottomForeground="White"
  • BottomIcon="Play"
  • BottomLabel="Next"
Bottom part of the control and
  • TopBackground="OrangeRed"
  • TopCommand="{Binding DataContext.CallTopActionItemCommand, RelativeSource={RelativeSource TemplatedParent}}"
  • TopForeground="White"
  • TopIcon="Delete"
  • TopLabel="Delete"
for the top part of the control, changing these are what will allow you to change how the control behaves.

You can find my code and the sample here.

Happy coding!

mercredi 4 octobre 2017

Editing the HTTP header done by your WebView using NavigationStarting in a UWP application [HTML,C#]

I recently encounter a very weird issue with how my WebView was doing some of  my HTTP calls on redirects.  Sometimes when calling a URL that will do a redirect the HTTP headers would get lost or replaced by some default values.

To fix this the only solution that I found was to override the HTTP query done every time the WebView started navigating to another page.   In this I was lucky as we have a NavigationStarting event that is fired when this happens, thus I have NavigationStarting += Wb_NavigationStarting; when I am creating my WebView.

Now that ce have caught this event we need to edit  it in Wb_NavigationStarting method, I will unbind the event (so that it dosent fire multiple times), tell the WebView that I am handling the event with args.Cancel = true; and now edit the HTTP query with a method that I will call NavigateWithHeader .

In the method NavigateWithHeader I will just add again my header and my authorization token so that the HTTP query has all of the values it is supposed to have, you will have something like this:

var requestMsg = new Windows.Web.Http.HttpRequestMessage(HttpMethod.Get, uri);
requestMsg.Headers.Add("User-Agent", "some user agent");
requestMsg.Headers.Add("Authorization", "token abc");                      
MyWebView.NavigateWithHttpRequestMessage(requestMsg);
MyWebView.NavigationStarting += Wb_NavigationStarting;


 Here is the full code:


 private WebView NewWebView()
        {
            var webView = new WebView(WebViewExecutionMode.SameThread);
            webView.NavigationStarting += Wb_NavigationStarting;         
            return webView;
        }     

private void NavigateWithHeader(Uri uri)
        {
            var requestMsg = new Windows.Web.Http.HttpRequestMessage(HttpMethod.Get, uri);
            requestMsg.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063");
            MyWebView.NavigateWithHttpRequestMessage(requestMsg);
            MyWebView.NavigationStarting += Wb_NavigationStarting;
        }

private void Wb_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
        {
            MyWebView.NavigationStarting -= Wb_NavigationStarting;
            args.Cancel = true;
            NavigateWithHeader(args.Uri);
        }

Happy Coding!

mercredi 20 septembre 2017

Setting a cookie and HTTP headers in your WebView in a UWP application [WebView,C#]

In this post we will see how to set values in the header and the cookie of your WebView in a UWP application.

First we need a method to create a new WebView:

//Creating a new webview
private WebView NewWebView()
        {
            var webView = new WebView(WebViewExecutionMode.SameThread);
            return webView;
        }

To edit the HTTP header that will be called by the WebView, and because we are using HttpRequestMessage from the Windows.Web.Http namespace.  We will edit the header like we would normally by creating a HttpRequestMessage property and adding a header by using Headers.Add:

private HttpRequestMessage NewRequest(Uri url)
       {
            var message = new HttpRequestMessage(HttpMethod.Get, url);
            
            //adding User Agent to header            
            message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063");
            
            //adding Authorization to header
message.Headers.Add("Authorization", "Bearer xxxxxxxxxxxx"); return message; }


Next here is how we can set cookies for our WebView, make sur that for the HttpCookie(key, ".YourDomain.com", "/") you set the correct domain or it will not work. Make sur that you set all the value correct (if the cookie is for a third party then make sure that SetCookie is set to TRUE and not false).

private void SetCookieInWebView(string key, string value)
        {
            Windows.Web.Http.Filters.HttpBaseProtocolFilter filter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
            Windows.Web.Http.HttpCookie cookie = new Windows.Web.Http.HttpCookie(key, ".YourDomain.com", "/");
            cookie.Value = value;
            filter.CookieManager.SetCookie(cookie, false);
        }
 
And lastly is how you could for example use all of these methods together.

//creating a new WebView
MyWebView = NewWebView();

//Setting cookies
SetCookieInWebView("Key1", "xxxxxxxxxxxxxxx"); SetCookieInWebView("Key2", "aaaaaaaaaaaaaaaa"); SetCookieInWebView("Key3", "bbbbbbbbbbbb"); //creating http request message to send to the webview HttpRequestMessage request = NewRequest("http:// xxxxx .com"); //doing http call MyWebView.NavigateWithHttpRequestMessage(request);

Happy Coding!