mercredi 21 février 2018

WebView using InvokeScriptAsync and calling a method and passing the parameters using JSON.parse [WebView,C#]

Calling a method on your WebView is simple just call the WebView.InvokeScriptAsync( method , param) (more information on MSDN) and you are good to go.  However imagine if you need to send json in the param, how do you send it?


This is the issue that we are going to have a quick look in the post, here is an example in of a javascript call that needs to be called with JSON data.  Looking at the MSDN documentation  , we can see that we need to surrond ou json string with JSON.parse({0}), in the params value in the InvokeScriptAsync.

Here is an example of the method name 'eval' and the javascript parameter that I would like to send to the UWP WebView:

 loadUrl javascript:object.load('xsazphf',
JSON.parse('{  
   "props":{  
      "param":{  
         "action":{  
            "gesture":"click",
            "id":"63825b13-dff5-4f45-81e9-a9dbe2aca39b"
         },
         "screen":{ 
            "id":"662dfa95-6ad2-43c1-b403-4e9a4118be4c"
         },
         "section":{  
            "id":"2bcd2be7-9c10-49e9-b71e-b77dee17c7fb",
            "index":1
         }
      }
   }
}'))

All in all,the json string that we want to pass to our javascript object needs to be wrapped in JSON.parse('{0}')).  This will allow the javascript to understand that the data that we are passing is JSON.

When we are building our string to call with the eval function in javasciprt  we will need to have some like this : myJsObject.MyMethode(Paramater1, ,JSON.parse("MyJSONStringFormat")) , when using StringBuilder we just need follow the pattern above.

Here is the code that will help you pass the correct string to your webview:

        public async void CallPlayerMethod(string method, string param, string json)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("myJSObject.");
            builder.Append(method);
            builder.Append(string.Format("('{0}'", param)) ;
            builder.Append(string.Format(",JSON.parse('{0}'))", json));  
// old
            //builder.Append('(');
            //builder.Append("'" + param + "'");
            //builder.Append(",JSON.parse('" + json + "')");
            //builder.Append(')');
//call webview CallEvalWebviewMethod(builder.ToString()); } private async void CallEvalWebviewMethod(string callMethod) {
            List<string> callingJsMethod = new List<string>();
            callingJsMethod.Add(callMethod);

            try
            {
                await MyWebView?.InvokeScriptAsync("eval", callingJsMethod);
            }
            catch (Exception e)
            {
                //silent fail
            }
        }

You can find my sample here
Happy coding





lundi 19 février 2018

Building a Placeholder Loading UI like Facebook using only XAML for your UWP application [XAML,C#,Composition]

Building beautiful native UI is very important, and keeping your users informed of what is going in the app is even more important.

We are going to look at creating a placeholder loading control that looks like what facebook is using in its application.

Here is a static version of the loading control:


Here is what we could do if we add some animation using composition.

It is super important to remember that the loading animation should not hide or distract the user from using y our application, the loading animation should just be there to help your user understand that they must wait a bit for the loading to end.

For this example we will be build 2 different UI loaders to show that data is being loaded, here is what the placeholders will have to show that they are loading:



Here is an example of what we want to do:


You have two options either we have a control with a shimmer over to simulate that something is loading or we just have a static rectangle (or grid) with a background color.   If you only want to use the backgroudn color you can look at the RectangleNoShimmerControl.xaml file, if you do want the shimmer keep on reading =).

First we are going to create a RectangleControl UserControl that will hold a ContentControl and a StackPanel with a FontIcon.

The ContentControl with its LinearGradientBrush is what will allow you have the gradient effect when we move the element, in the samlpe you can change: 
<GradientStop Offset="0.5" Color="#dcdcdc" />
by
<GradientStop Offset="0.5" Color="Red" />

which will give you this for example:

Next we will need to add the animation on the content control, we need something to move on the X axis, so using a DoubleAnimationUsingKeyFrames  and targeting  CompositeTransform.TranslateX  we will be able to do this.

<Storyboard>
    <DoubleAnimationUsingKeyFrames
            EnableDependentAnimation="True"
            RepeatBehavior="Forever"
Storyboard.TargetName="contentControl" Storyboard.TargetProperty="(Control.Foreground).(Brush.RelativeTransform).(CompositeTransform.TranslateX)"> <EasingDoubleKeyFrame KeyTime="0" Value="-1" /> <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1" /> </DoubleAnimationUsingKeyFrames> </Storyboard>

We are going to nest our Storyboard inside a <Grid.Triggers> =>        <EventTrigger RoutedEvent="Grid.Loaded"> => <EventTrigger.Actions> which will allow us to start the animation when the Grid is loaded.

Here is the full XAML code for the page:

    <UserControl.Resources>         
        <Color x:Key="EmptyStateLightgray">#ebebeb</Color>
        <Color x:Key="EmptyStatebackground">#f7f7f7</Color>
        <SolidColorBrush x:Key="EmptyStateColorBrush" Color="{StaticResource EmptyStateLightgray}" />
    </UserControl.Resources>

     <Grid>
        <Grid.Triggers>
            <EventTrigger RoutedEvent="Grid.Loaded">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimationUsingKeyFrames
                                EnableDependentAnimation="True"
                                RepeatBehavior="Forever"
                                Storyboard.TargetName="contentControl"
                                Storyboard.TargetProperty="(Control.Foreground).(Brush.RelativeTransform).(CompositeTransform.TranslateX)">
                                <EasingDoubleKeyFrame KeyTime="0" Value="-1" />
                                <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1" />
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Grid.Triggers>
<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"> <ContentControl.Foreground> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.RelativeTransform> <CompositeTransform CenterX="0.5" CenterY="0.5" Rotation="95" /> </LinearGradientBrush.RelativeTransform> <GradientStop Offset="0" Color="{StaticResource EmptyStateLightgray}" /> <GradientStop Offset="0.5" Color="#dcdcdc" /> <GradientStop Offset="1" Color="{StaticResource EmptyStateLightgray}" /> </LinearGradientBrush> </ContentControl.Foreground> <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{StaticResource EmptyStateColorBrush}"> <FontIcon FontSize="800" Glyph="&#xE009;" /> </StackPanel> </ContentControl> </Grid>


Now that we have our Facebook like shimmer animation we will create our loading states using that UserControl. Now we are going to create another UserControl to resemble something like this:
To create this in XAML I will use a Grid which will use multiple RowDefinitions , which gives us this:


<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="120" />
            <RowDefinition Height="15" />
            <RowDefinition Height="20" />
            <RowDefinition Height="15" />
        </Grid.RowDefinitions>

        <local:RectangleControl
            Grid.Row="0"
            Width="290"
            Margin="0"
            />
        <local:RectangleControl
            Grid.Row="1"
            Width="60"
            Margin="0,5,0,0"
            />
        <local:RectangleControl
            Grid.Row="2"
            Width="210"
            Margin="0,9,0,0"
            />
        <local:RectangleControl
            Grid.Row="3"
            Width="170"
            Margin="0,5,0,0"
            />
    </Grid>

You can find my code sample here.
Happy coding 



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. that you can create custom controls to make beautiful UI

I am not in the habit of writing negative posts and this is not one, so let me explain why we should hold off just a bit before we really start using this:
  • 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 working however there as still a lot of missing pieces.  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, it has more limitation because it is being vitalized.
  • Currently Rendering custom controls on Tizen with Xamrin is not working which can also be issue as you can imagine. In my case I was trying to create a listview that we holding another listview horizontally, this worked fine on the UWP app but nothing happened of the Tizen TV App. 

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!