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!