Quantcast
Channel: Telerik Blogs | .NET
Viewing all 1954 articles
Browse latest View live

An Overview of Telerik Fiddler

$
0
0

Telerik Fiddler is a web debugging proxy that's incredibly useful for developers. This post provides an overview of Telerik Fiddler.

Telerik Fiddler (or Fiddler) is a special-purpose proxy server for debugging web traffic from applications like browsers. It’s used to capture and record this web traffic and then forward it onto a web server. The server’s responses are then returned to Fiddler and then returned back to the client.

The recorded web traffic is presented through a session list in the Fiddler UI:

Nearly all programs that use web protocols support proxy servers. As a result, Fiddler can be used with most applications without need for further configuration. When Fiddler starts to capture traffic, it registers itself with the Windows Internet (WinINet) networking component and requests that all applications begin directing their requests to Fiddler.

A small set of applications do not automatically respect the Windows networking configuration and may require manual configuration in order for Fiddler to capture their traffic. Fiddler can be configured to work in these scenarios, including server-to-server (e.g. web services) and device-to-server traffic (e.g. mobile device clients). By default, Fiddler is designed to automatically chain to any upstream proxy server that was configured before it began capturing - this allows Fiddler to work in network environments where a proxy server is already in use.

Because Fiddler captures traffic from all locally-running processes, it supports a wide range of filters. These enable you to hide traffict that is not of interest to you, as well as highlighting traffic you deem interesting (using colors or font choice). Filters can be applied based on the source of the traffic (e.g. the specific client process) or based on some characteristic of the traffic itself (e.g. what hostname the traffic is bound for, or what type of content the server returned).

Fiddler supports a rich extensibility model which ranges from simple FiddlerScript (C# or JScript 10.0) to powerful extensions which can be developed using any .NET language. Fiddler also supports several special-purpose extension types. The most popular are inspectors, which enable you to inspect requests/responses. Inspectors can be built to display all response types (e.g. the HexView inspector) or tailored to support a type-specific format (e.g. the JSON inspector). If you’re a developer, you can build Fiddler’s core proxy engine into your applications using a class library named FiddlerCore.

Fiddler can decrypt HTTPS traffic and display and modify the requests that would otherwise be inscrutable to observers on the network using a man-in-the-middle decryption technique. To permit seamless debugging without security warnings, Fiddler’s root certificate may be installed in the Trusted Certificates store of the system or web browser.

A web session represents a single transaction between a client and a server. Each session appears as a single entry in the Web Sessions List in the Fiddler interface. Each session object has a request and a response, representing what the client sent to the server and what the server returned to the client. The session object also maintains a set of flags that record metadata about the session, and a timers object that stores timestamps logged in the course of processing the session.

Proxy servers are not limited to simply viewing network traffic; Fiddler got its name from its ability to “fiddle” with outbound requests and inbound responses. Manual tampering of traffic may be performed by setting a request or response breakpoint. When a breakpoint is set, Fiddler will pause the processing of the session and permit manual alteration of the request and the response.

Traffic rewriting may also be performed automatically by script or extensions running inside of Fiddler. By default, Fiddler operates in buffering mode, whereby the server’s response is completely collected before any part of it is sent to the client. If the streaming mode is instead enabled, the server’s response will be immediately returned to the client as it is downloaded. In streaming mode, response tampering is not possible.

Captured sessions can be saved in a Session Archive Zip (SAZ) file for later viewing. This compressed file format contains the full request and response, as well as flags, timers, and other metadata. A lightweight capture-only tool known as FiddlerCap may be used by non-technical users to collect a SAZ file for analysis by experts. Fiddler supports Exporter extensions that allow storing captured sessions in myriad other formats for interoperability with other tools. Similarly, Fiddler supports Importer extensions that enable Fiddler to load traffic stored in other formats, including the HTTP Archive (HAR) format used by many browsers’ developer tools.

Usage Scenarios

Some of the most common questions are of the form: “Can I use Fiddler to accomplish [x]?” While there are a huge number of scenarios for which Fiddler is useful, and a number of scenarios for which Fiddler isn’t suitable, the most common tasks fall into a few buckets. Here’s a rough guide to what you can and cannot do with Fiddler:

An Incomplete List of Things Fiddler Can Do

  • View web traffic from nearly any browser, client application, or service.
  • Modify any request or response, either manually or automatically.
  • Decrypt HTTPS traffic to enable viewing and modification.
  • Store captured traffic to an archive and reload it later, even from a different computer.
  • Playback previously-captured responses to a client application, even if the server is offline.
  • Debug web traffic from most PCs and devices, including macOS/Linux systems and mobile devices.
  • Chain to upstream proxy servers, including the Tor network.
  • Run as a reverse proxy on a server to capture traffic without reconfiguring the client computer or device.
  • Grow more powerful with new features added by FiddlerScript or the .NET-based extensibility model.

An Incomplete List of Things Fiddler Cannot Do

While Fiddler is a very flexible tool, there are some things it cannot presently do. That list includes:

  • Debug non-web protocol traffic.
    • Fiddler works with HTTP, HTTPS, and FTP traffic and related protocols like HTML5 WebSockets and ICY streams.
    • Fiddler cannot “see” or alter traffic that runs on other protocols like SMTP, POP3, Telnet, IRC, etc.
    • Handle huge requests or responses.
  • Fiddler cannot handle requests larger than 2 GB in size.
    • Fiddler has limited ability to handle responses larger than 2 GB.
    • Fiddler uses system memory and the pagefile to hold session data. Storing large numbers of sessions or huge requests or responses can result in slow performance.
  • “Magically” remove bugs in a website for you.
    • While Fiddler will identify networking problems on your behalf, it generally cannot fix them without your help. I can’t tell you how many times I’ve gotten emails asking: “What gives? I installed Fiddler but my website still has bugs!”

The above text is a modified excerpt from the book, “Debugging with Fiddler, Second Edition” by Eric Lawrence. Options for purchasing this book can be found at fiddlerbook.com.


Copying and Cloning Arrays in C#

$
0
0

Learn how to copy elements from one array to another using the provided functions in System.Array class.

An array in C# is a collection of data items, all of the same type and accessed using a numeral index. The Array class provides methods for creating, manipulating, searching, and sorting arrays in .NET. There will be situations where you want to work with a new array but copy items from an existing array to it, or copy items from one array into another array. I’ll show you how to do this using some available methods in the Array class.

Array.CopyTo

Array.CopyTo copies all the elements of the current array to the specified destination array. This method should be called from the source array and it takes two parameters. The first being the array you want to copy to, and the second parameter tells it what index of the destination array it should start copying into. Let’s take a look at an example.

var source = new[] { "Ally", "Bishop", "Billy" };
var target = new string[4];

source.CopyTo(target, 1);
foreach (var item in target)
{
  Console.WriteLine(item);
}

// output:

// Ally
// Bishop
// Billy

The code above copies all items in the source array to the target array. It copies elements from the source to the target array object starting at index 1; therefore, index 0 of the target array is null.

Array.ConstrainedCopy

Array.ConstrainedCopy is similar to Array.CopyTo. The difference is that Array.ConstrainedCopy guarantees that all changes are undone if the copy operation does not succeed completely because of some exception. Here’s an example of how Array.CopyTo behaves when it encounters an exception.

var source = new object[] { "Ally", "Bishop", 1 };
var target = new string[3];

try
{
  source.CopyTo(target, 0);
}
catch (InvalidCastException)
{
  foreach (var element in target)
  {
    Console.WriteLine(element);
  }
}

Console.Read();

// output:

// Ally
// Bishop

Above, we have a source array that has elements of string and object type. We copy the content from the source array into a target array, which is a string type. When this code runs, it’ll encounter an InvalidCastException when it tries to copy the last element, which does not match the type of the target array. The copy operation fails at that point, but the target array already has some of the element from the source array from what we see printed in the console. Let’s try a similar example with ConstrainedCopy:

var source = new object[] { "Ally", "Bishop", 1 };
var target = new string[3];

try
{
  Array.ConstrainedCopy(source, 0, target, 0, 3);
}
catch (ArrayTypeMismatchException)
{
  Console.WriteLine(target[0]);
  Console.WriteLine(target[1]);
}

Console.Read();

Array.ConstrainedCopy takes five (5) parameters: the source array and its starting index, the target array and its starting index, and an integer representing the number of elements to copy. When the code above runs, it encounters an exception, and, when you check the content of the target array, you’ll notice it has nothing in it, unlike Array.CopyTo.

Array.ConvertAll

Array.ConvertAll is used to convert an array of one type to an array of a different type. The method takes the source array as the first parameter, and then a second parameter of Converter<TInput,TOutput> delegate. This delegate represents a conversion function to convert from one type to another.

Assume the following class:

class Person
{
  public Person(string name)
  {
    Name = name;
  }
  public string Name { get; private set; }
}

Here is an example of Array.ConvertAll being used with this type:

var source = new[] { "Ally", "Bishop", "Billy" };
var target = Array.ConvertAll(source, x => new Person(x));

foreach (var item in target)
{
  Console.WriteLine(item.Name);
}
Console.Read();

// output:

// Ally
// Bishop
// Billy

Here we are taking an array of string and making a new array of Person out of it. This comes in handy when we want to make a new array that copies data from another array.

Array.Clone Method

Array.Clone does a shallow copy of all the elements in the source array and returns an object containing those elements. Here’s an example of how you can use this method:

static void Main(string[] args)
{
  var source = new[] { "Ally", "Bishop", "Billy" };
  var target = (string[])source.Clone();
  foreach (var element in target)
  {
    Console.WriteLine(element);
  }

  Console.Read();
}

// output:

// Ally
// Bishop
// Billy

Array.Clone returns an object that we have to cast to an array of strings. This differs from Array.CopyTo because it doesn’t require a target/destination array to be available when calling the function, whereas Array.CopyTo requires a destination array and an index.

Conclusion

The Array class in C# is very useful when working with a collection of data. It provides methods for creating, manipulating, searching, and sorting arrays. In this post, I showed you how to copy data from one array object to another. You saw the various methods available from the Array class. They are Clone, CopyTo, ConstrainedCopy, and ConvertAll methods. The various examples showed you how to use these methods, and I believe this should leave you with additional knowledge on working with arrays in C#.

Feel free to leave a comment if you have any questions. Happy coding!

Health Checks in ASP.NET Core

$
0
0

Learn how to configure and develop health checks in ASP.NET Core to confirm the health of your application.

Health checks are a new middleware available in ASP.NET Core 2.2. It provides a way to expose the health of your application through an HTTP endpoint.

The health of your application can mean many things. It's up to you to configure what is considered healthy or unhealthy.

Maybe your application is reliant on the ability to connect to a database. If your application cannot connect to the database, then the health check endpoint would respond as unhealthy.

Other scenarios could include confirming the environment that is hosting the application is in a healthy state. For example, memory usage, disk space, etc.
If you have used a load balancer you've probably used at least a basic health check. Likewise, if you've used docker, you may be familiar with its HEALTHCHECK.

In a load balancing scenario, this means that the load balancer periodically makes an HTTP request to your health check endpoint. If it receives a HTTP 200 OK status, then it adds the application to the load balancer pool and live HTTP traffic will be routed to that instance.

If it responds with an unhealthy status (usually anything other than HTTP 200 OK), it will not add or remove it from the load balancer pool.

Basics

The bare minimum to get health checks added to your application are to modify the Startup.cs file by adding health checks to the ConfigureServices and Configure methods appropriately.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AspNetCore.HealthCheck.Demo
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddHealthChecks();
      services.AddDbContext<MyDbContext>();
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
      app.UseHealthChecks("/health");
      app.UseStaticFiles();
      app.UseMvc();
    }
  }
}

When you browse to the /health route, you will receive an HTTP 200 OK with the content body of Healthy.

Custom Health Check

One common health check might be to verify that we can connect to our database. In this example, I have an Entity Framework Core DbContext called MyDbContext, which is registered in ConfigureServices().

In order to test our database connection, we can create a custom health check. To do so, we need to implement IHealthCheck. The CheckhealthAsync requires us to return a HealthCheckStatus. If we are able to connect to the database, we will return Healthy; otherwise, we will return Unhealthy.

You will also notice that we are using dependency injection through the constructor. Anything registered in ConfigureServices() is available for us to inject in the constructor of our health check.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace AspNetCore.HealthCheck.Demo
{
  public class DbContextHealthCheck : IHealthCheck
  {
    private readonly MyDbContext _dbContext;


    public DbContextHealthCheck(MyDbContext dbContext)
    {
      _dbContext = dbContext;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
      CancellationToken cancellationToken = new CancellationToken())
    {
      return await _dbContext.Database.CanConnectAsync(cancellationToken)
              ? HealthCheckResult.Healthy()
              : HealthCheckResult.Unhealthy();
    }
  }
}

Now, in order to use add new health check, we can use Addcheck() to AddHealthChecks() in ConfigureServices():

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AspNetCore.HealthCheck.Demo
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddDbContext<MyDbContext>();

      services.AddHealthChecks()
              .AddCheck<MyDbContextHealthCheck>("DbContextHealthCheck");

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
      app.UseHealthChecks("/health");           
      app.UseStaticFiles();
      app.UseMvc();
    }
  }
}

Built-in EF Core Check

Luckily, we don't actually need to create an EF Core DbContext check as Microsoft has already done so in the Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore NuGet Package. We can simply use this package and then change our check to the following:

services.AddHealthChecks()
        .AddDbContextCheck<MyDbContext>("DbContextHealthCheck");

Community Packages

There are a bunch of health check packages on NuGet for SQL Server, MySQL, MongoDB, Redis, RabbitMQ, Elasticsearch, Azure Storage, Amazon S3, and many more.

You can find all of these on AspNetCore.Diagnostics.HealthChecks repository on GitHub that reference each NuGet package.

Here's a couple examples of how easily they are to add to your Startup's ConfigureServices():

AspNetCore.HealthChecks.SqlServer

public void ConfigureServices(IServiceCollection services)
{
  services.AddHealthChecks()
          .AddSqlServer(Configuration["Data:ConnectionStrings:Sql"])
}

AspNetCore.HealthChecks.Redis

public void ConfigureServices(IServiceCollection services)
{
  services.AddHealthChecks()
          .AddRedis(Configuration["Data:ConnectionStrings:Redis"])
}

Options

There are a few different options for configuring how the health check middleware behaves.

Status Codes

In our own DbContextHealthCheck, we returned a Healthy status if our application can connect to our database. Otherwise, we returned an Unhealthy status.

This results in the /health endpoint returning different HTTP status codes depending on our HealthStatus. By default, healthy will return a HTTP Status of 200 OK. Unhealthy will return a 503 Service Unavailable. We can modify this default behavior by using HealthCheckOptions to create our mappings between HealthStatus and StatusCodes.

app.UseHealthChecks("/health", new HealthCheckOptions
{
  ResultStatusCodes =
  {
    [HealthStatus.Healthy] = StatusCodes.Status200OK,
    [HealthStatus.Degraded] = StatusCodes.Status200OK,
    [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
  }
});

There is a third status code: Degraded. By default, this will also return a 200 OK status.

Response

By default, the Content-Type of the response will be text/plain and the response body will be Healthy or Unhealthy.

Another option you may want to configure is the actual response body of the endpoint. You can control the output by configuring the ResponseWriter in the HealthCheckOptions.

Instead of returning plain text, I'll serialize the HealthReport to JSON:

app.UseHealthChecks("/health", new HealthCheckOptions
{
  ResponseWriter = async (context, report) =>
  {
    context.Response.ContentType = "application/json; charset=utf-8";
    var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(report));
    await context.Response.Body.WriteAsync(bytes);
  }
});

This results in our /health endpoint returning:

Content-Type: application/json; charset=utf-8
Server: Kestrel
Cache-Control: no-store, no-cache
Pragma:no-cache
Transfer-Encoding: chunked
Expires: Thu, 01 Jan 1970 00:00:00 GMT
{
  "Entries": {
    "DbContextHealthCheck": {
      "Data": {},
      "Description": null,
      "Duration": "00:00:00.0265244",
      "Exception": null,
      "Status": 2
    }
  },
  "Status": 2,
  "TotalDuration": "00:00:00.0302606"
}

Timeouts

One thing to consider when creating health checks is timeouts. For example, maybe you've created a health check is testing a database connection or perhaps you are using HttpClient to verify you can make an external HTTP connection.

Often, these clients (DbConnection or HttpClient) have default timeout lengths that can be fairly high. HttpClient has a default of 100 seconds.

If you are using the health check endpoint for a load balancer to determine the health of your application, you want to have it return its health status as quickly as possible. If you have a internet connection issue, you may not want to wait 100 seconds to return a 503 Service Unavailable. This will delay your load balancer from removing your application from the pool.

Web UI

There is another excellent package, AspNetCore.HealthChecks.UI that adds a web UI to your app. This allows you to visualize the health checks you have configured and their status.

Once the package is installed, you need to call AddHealthChecksUI() to ConfigureServices() as well as call UseHealthChecksUI() from Configure() in your Startup.

You also need to configure the ResponseWrite to use the UIResponseWriter.WriteHealthCheckUIResponse. This essentially does what we have above by serializing the HealthReport to JSON. This is required by the HealthCheck-UI in order for it to get detailed information about your configured health checks.

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
  }

  public IConfiguration Configuration { get; }

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddDbContext<MyDbContext>();


    services.AddHealthChecks()
            .AddCheck<MyDbContextHealthCheck>("DbContextHealthCheck");
    
    services.AddHealthChecksUI();
    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    app.UseHealthChecks("/health", new HealthCheckOptions()
    {
      Predicate = _ => true,
      ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
    });
    
    app.UseHealthChecksUI();
    
    app.UseStaticFiles();
    app.UseMvc();
  }
}

This will add a new route to your application at /healthchecks-ui.

You also need to add some configuration to appsettings.json (or whatever configuration you are pulling from).

This tells the HealthChecks-UI where to poll for the detailed health check information. Because of this, you could add as many different URLs for various other ASP.NET Core applications that are returning health check data.

For our example, we will just add our local endpoint we have running at /health:

"HealthChecks-UI": {
  "HealthChecks": [
    {
      "Name": "Local",
      "Uri": "http://localhost:5000/health"
    }
  ],
  "EvaluationTimeOnSeconds": 10,
  "MinimumSecondsBetweenFailureNotifications": 60
}

Now when you browse to /healtchecks-ui, you will see the UI with a listing of our health checks:

Health Check UI

Summary

The health check middleware is a great new addition to ASP.NET Core. It is configurable and very easy to add your own new health checks. The community is already releasing many different packages for various external services, and I can only assume they will increase in the future.

For More on Developing with ASP.NET Core

Want to learn about creating great user interfaces with ASP.NET Core? Check out Telerik UI for ASP.NET Core, with everything from grids and charts to schedulers and pickers.

Xamarin.Forms + SkiaSharp: Create Awesome Cross-Platform Animations in Your Mobile App

$
0
0

SkiaSharp is an open source .NET wrapper library over Google's Skia, developed and maintained by Xamarin engineers. Read on to learn how to create awesome animations in your mobile app using Xamarin.Forms and SkiaSharp.

It gives me great pleasure to share with you about some of my favorite topics in software development: computer graphics and mobile applications. I’ve been in love with graphics since I was a kid — I loved drawing on paper, and, when my parents got me my first home computer, an amazing ZX Spectrum, I became completely fascinated by computer graphics.

SkiaSharp is a .NET open-source wrapper library of the Skia graphics engine, and in combination with Xamarin.Forms, which is a great cross-platform open-source mobile app development framework, you can give your mobile apps new life.

Skia, the Star Performer

Skia is a high performance and open-source 2D graphics engine written in C++. It’s owned and backed by Google. As a proof of its solid performance, it’s been used in several mainstream products, such as Google Chrome, Chrome OS, Android or Mozilla FireFox, just to name a few. The Skia repository can be found here: https://github.com/google/skia

Skia has native library versions for Android, iOS, Mac, Windows, and ChromeOS.

As you’d expect from a 2D graphics engine, Skia has API to draw graphics primitives such as text, geometries and images. It has an immediate rendering mode API, so for every call you do with the Skia API, it’s going to be quickly drawn on the screen.

A Sharp Skia

SkiaSharp is a .NET wrapper library over Google’s Skia, developed and maintained by Xamarin engineers and, of course, it’s completely open source under the MIT license. You can check out its source code repository on Github: https://github.com/mono/SkiaSharp

On non-Windows platforms, SkiaSharp runs on top of Xamarin, and, as with any .NET library, the easiest way to add SkiaSharp to your projects is by NuGet: https://www.nuget.org/packages/SkiaSharp

SkiaSharp Canvas View

In order to actually see on the screen what you draw with SkiaSharp API, SkiaSharp provides a canvas control on every platform it supports. This is done by SkiaSharp.Views, an extension library sitting on top of SkiaSharp: https://www.nuget.org/packages/SkiaSharp.Views.Forms.

Here are few examples of the canvas native control, which SkiaSharp provides on some platforms:

// Xamarin.iOSpublicclassSKCanvasView: UIView, IComponent
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}// Xamarin.AndroidpublicclassSKSurfaceView: SurfaceView, ISurfaceHolderCallback
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}// MacpublicclassSKCanvasView: NSView
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}// UWPpublicpartialclassSKXamlCanvas: Canvas
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}// WPFpublicclassSKElement: FrameworkElement
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}

As you know, Xamarin.Forms has its own cross-platform API and controls wrapping the native APIs and controls. Therefore, for Xamarin.Forms apps, SkiaSharp has a dedicated library called SkiaSharp.Views.Forms: https://www.nuget.org/packages/SkiaSharp.Views.Forms

SkiaSharp.Views.Forms provides a Xamarin.Forms control for the canvas, the SkCanvasView:

// Xamarin.FormspublicclassSKCanvasView: View, ISKCanvasViewController
{publicevent EventHandler<SKPaintSurfaceEventArgs> PaintSurface;}

Under the hood, the Xamarin.Forms renderers for SKCanvasView use the same native views which share same implementation as in SkiaSharp.Views

Drawing on the SkiaSharp Canvas View

As you can see above, on all platforms, the SkiCanvasView has a PaintSurface event. It fires the event when canvas needs to be painted, either because the view was resized or because you called InvalidateSurface() method on it:

_skCanvasView.InvalidateSurface();

On the event handler, you get an instance of SkiCanvas, which you can use to draw with the SkiaSharp API:

...
_skCanvasView.PaintSurface += SkCanvasViewRequiredPainting;...voidSkCanvasViewRequiredPainting(object sender, SKPaintSurfaceEventArgs e){
SKSurface skSurface = e.Surface;
SKCanvas skCanvas = skSurface.Canvas;
skCanvas.Clear();var paint =newSKPaint(){
Style = SKPaintStyle.Stroke,
Color = Color.Blue.ToSKColor(),
StrokeWidth =10};// Draw on the skCanvas instance using SkiaSharp API
skCanvas.DrawRect(x, y, width, height, paint);}

I think it’s impressive to see how the combination of Xamarin, Xamarin.Forms and SkiaSharp brings .NET and Skia together on so many different platforms and provides a cross-platform .NET API for mobile app development and Skia!

This article talks about using Xamarin.Forms and SkiaSharp, so what you will read about next uses the SkCanvasView from the SkiaSharp.Views.Forms library.

Implementing an Animated Highlight in a Mobile App with Xamarin.Forms and SkiaSharp

As an example, I’m going to show how to build a highlight that moves between inputs and a button on a sign-up form, creating a captivating animation effect. The app is built with Xamarin.Forms, Skia.Sharp and C#, which runs seamlessly on Android and iOS. Here’s a screen capture of the final application running in the iOS simulator: https://www.youtube.com/watch?v=BBZWcWjJO_g

You can check out the complete source code of the app in my repository on GitHub: https://github.com/andreinitescu/AnimatedHighlightApp

The implementation is in C# and it’s 100% shared across the platforms — there’s no custom platform-specific code involved, no Xamarin.Forms renderers and no effects were used. I haven’t tested it on other platforms supported by Xamarin.Forms and SkiaSharp, but I’m sure the code runs very well on those too.

Credit goes to the following sources and their authors for the animation design idea:

Implementing the Highlight

The highlight effect is created by a combination of drawing a geometric path with SkiaSharp API and animating the visible part of the path using the Xamarin.Forms animation API. Here are the main steps I followed in my implementation:

  1. Create the sign-up form layout

  2. Build and draw SkPath on SkCanvasView based on the position of form elements in the container layout

  3. Making a certain part of SkPath visible using dash effect

  4. Animating the highlight between elements

Create the Sign-Up Form Layout

The sign-up form has three Entry elements to enter username, password and confirm password, and a Button to submit. I’m using a StackLayout as the container for the form elements, but any other container would work:

<StackLayoutx:Name="_formLayout"...><LabelText="Username"
Style="{StaticResource FormLabelStyle}"/><Entry Style="{StaticResource FormEntryStyle}"Focused="EntryFocused"/><LabelText="Password"Margin="0, 15, 0, 0"
Style="{StaticResource FormLabelStyle}"/><EntryIsPassword="True"
Style="{StaticResource FormEntryStyle}"Focused="EntryFocused"/><LabelText="Confirm Password"Margin="0, 15, 0, 0"
Style="{StaticResource FormLabelStyle}"/><EntryIsPassword="True"
Style="{StaticResource FormEntryStyle}"Focused="EntryFocused"/><ButtonText="Sign-Up"Margin="0, 40, 0, 0"
Style="{StaticResource FormSubmitBtnStyle}"Clicked="ButtonClicked"/></StackLayout>

Build and Draw SkPath on SkCanvasView Based on the Position of Form Elements in the Container Layout

The actual highlight line is a geometric path drawn using SkiaSharp API. Using the position of every Xamarin.Forms element on the form layout, I’m creating a SkPath connecting all the form elements and then drawing the created SkPath on the SKCanvasView view. Here’s how the complete SkPath looks like:

COMPLE~1

To make the implementation easier, it’s important that the SKCanvasView has the same top-left screen coordinates as the StackLayout form layout. This makes it easier to compute the translation between the position of the Xamarin.Forms element within the StackLayout to the SkiaSharp position used to draw the SkPath on the SKCanvasView. Here’s the XAML, which shows the SkCanvasView and the form layout wrapped in a Grid:

<Grid><Grid.ColumnDefinitions><ColumnDefinitionWidth="Auto"/></Grid.ColumnDefinitions><skiaSharp:SKCanvasViewx:Name="_skCanvasView"PaintSurface="SkCanvasViewRequiredPainting"SizeChanged="SkCanvasViewSizeChanged"/><StackLayoutx:Name="_formLayout"...>
...
</StackLayout></Grid>

The creation of the SkPath based on the position of Xamarin.Forms elements is implemented in the CreatePathHighlightInfo method here.

Making Certain Part of SkPath Visible Using Dash Path Effect

When an element receives focus, I make visible only the part of the SkPath which is meant to represent the focused element highlight:

DASH_P~1

This is accomplished by creating a dash path effect (SkPathEffect) and painting with it the SkPath:

paint.PathEffect = SKPathEffect.CreateDash(intervals: strokeDash.Interval, phase: strokeDash.Phase);
skCanvas.DrawPath(skPath, paint);

As you can see, the CreatesDash API takes an interval array and a phase.

The intervals is an array of float values that indicate the length of the “on” interval and the length of “off” interval. For example, an intervals array with elements 10, 5 set on a line path, creates the effect of seeing 10 pixels followed by a gap of 5 pixels (assuming the stroke width is 1 pixel), and this succession repeats along the path:

DASH_I~1

The rule for this intervals array is that the array must contain least two values and it must be of an even number of values, and the values are interpreted as a succession of “on” and “off” intervals.

The phase value represents the offset used to draw the beginning of the dash. For example, if we have an interval of 10, 5 and phase is 5, we will see something like the following:

DASH_I~2

To highlight the first Entry for example, the “on” interval is the width of the Entry, the “off” interval is the remaining length of the path, and the phase is zero.

There’s more to know about how the stroke width and cap influence the path, which you can read about in the excellent Xamarin documentation for Skia.Sharp here.

As part of creating the path for the highlight, beside building the actual SkPath, I also build an array of dashes representing the dash path intervals corresponding to highlighting every Entry and Button element:

DASH_F~1

classHighlightPath{readonly Dictionary<int, StrokeDash> _strokeDashList =newDictionary<int, StrokeDash>();...}classStrokeDash{publicfloat[] Intervals {get;set;}publicfloat Phase {get;set;}...}

I’m using the position of the element on the form layout as a key to know how get the dash based on the focused element.

In my form, I have three Entry elements and one Button. The dash list will contain four entries representing the dash values which makes the path visible when every element has focus. Here is a screenshot with the dash values from debugger:

DASH_F~2

Animating the Highlight Between Elements

In order to make the highlight appear like it’s moving between the form elements, I animate the dash values (intervals and phase), from current dash values to the precalculated dash values corresponding to the element that must show highlight.

I started with creating my own StrokeDashAnimation class, which encapsulates animating the stroke dash intervals and phase values:

classStrokeDashAnimation{
StrokeDash _currStrokeDash;public StrokeDash From {get;}public StrokeDash To {get;}public TimeSpan Duration {get;}public Easing Easing {get;}publicStrokeDashAnimation(StrokeDash from, StrokeDash to, TimeSpan duration){
From =from;
To = to;
Duration = duration;}...}

I’m using StrokeDash class to encapsulate current dash value, which has the intervals and phase properties updated separately by every animation.

If you haven’t worked with animations in Xamarin.Forms, the framework has a very simple but very powerful support for creating animations based on animating a double value.

The way the Animation works is very simple: you give it a start double value, a double end value and an easing type. Animation uses easing to compute the interpolated value between the start and the end values. Once started using the Commit method, an Animation instance will call your callback for every computed value, starting with the given start value until end value is reached.

Animation can hold other Animation instances, and when you start the parent animation it starts its child animations.

You can read more about Xamarin.Forms animation and its capabilities here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/animation/

In my implementation, I create an animation holding three inner animations for every stroke dash property: interval “on”, interval “off” and phase:

classStrokeDashAnimation{
StrokeDash _currStrokeDash;public StrokeDash From {get;}public StrokeDash To {get;}public TimeSpan Duration {get;}public Easing Easing {get;}publicStrokeDashAnimation(StrokeDash from, StrokeDash to, TimeSpan duration){
From =from;
To = to;
Duration = duration;}publicvoidStart(Action<StrokeDash> onValueCallback){
_currStrokeDash = From;var anim =newAnimation((v)=>onValueCallback(_currStrokeDash));
anim.Add(0,1,newAnimation(
callback: v => _currStrokeDash.Phase =(float)v,
start: From.Phase,
end: To.Phase,
easing: Easing));
anim.Add(0,1,newAnimation(
callback: v => _currStrokeDash.Intervals[0]=(float)v,
start: From.Intervals[0],
end: To.Intervals[0],
easing: Easing));
anim.Add(0,1,newAnimation(
callback: v => _currStrokeDash.Intervals[1]=(float)v,
start: From.Intervals[1],
end: To.Intervals[1],
easing: Easing));
anim.Commit(
owner: Application.Current.MainPage,
name:"highlightAnimation",
length:(uint)Duration.TotalMilliseconds);}}

When the focus changes to an Entry or Button is clicked, I start the animation by animating from the current dash values to the precalculated dash values:

voidDrawDash(SKCanvasView skCanvasView, StrokeDash fromDash, StrokeDash toDash){if(fromDash !=null){var anim =newStrokeDashAnimation(from: fromDash,
to: toDash,
duration: _highlightSettings.AnimationDuration);
anim.Start((strokeDashToDraw)=>RequestDraw(skCanvasView, strokeDashToDraw));}elseRequestDraw(skCanvasView, toDash);}voidRequestDraw(SKCanvasView skCanvasView, StrokeDash strokeDashToDraw){
_highlightState.StrokeDash = strokeDashToDraw;
skCanvasView.InvalidateSurface();}

For every new computed stroke dash value, I invalidate the SkCanvasView surface in order to make it fire its PaintSurface event. On the paint event handler, I draw the path with the new dash values kept by _highlightState.StrokeDash:

publicvoidDraw(SKCanvasView skCanvasView, SKCanvas skCanvas){
skCanvas.Clear();if(_highlightState ==null)return;if(_skPaint ==null)
_skPaint =CreateHighlightSkPaint(skCanvasView, _highlightSettings, _highlightState.HighlightPath);
StrokeDash strokeDash = _highlightState.StrokeDash;// Comment the next line to see whole path without dash effect
_skPaint.PathEffect = SKPathEffect.CreateDash(strokeDash.Intervals, strokeDash.Phase);
skCanvas.DrawPath(_highlightState.HighlightPath.Path, _skPaint);}

Closing Words

I hope you can see the potential of combining the two awesome cross-platform APIs, Xamarin.Forms and SkiaSharp. Both frameworks have easy-to-use but powerful cross-platform APIs and would not exist without the giant on whose shoulders they are standing: Xamarin.

I hope you enjoyed reading this article. If you have any questions or feedback, feel free to reach out to me on Twitter or on my blog.

For More on Developing with Xamarin

Want to learn about creating great user interfaces with Xamarin? Check out Telerik UI for Xamarin, with everything from grids and charts to calendars and gauges.

Using Parcel.js in an ASP.NET Core Application

$
0
0

Parcel.js is a “Blazing fast, zero configuration web application bundler.” In this post, we’re going to take an ASP.NET Core website template that uses Bootstrap 4 and set it up to use Parcel-generated bundles instead.

ASP.NET Core supports bundling and minifying static assets at design-time using the community supported BuildBundlerMinifier package that can be configured in a bundleconfig.json file. However it’s not well suited for scenarios that would benefit from a deploy-time bundling strategy, i.e. assets are built during deployment and output files are not checked in.

This is where Parcel.js comes in. Parcel is a “Blazing fast, zero configuration web application bundler.” The zero-configuration bit is its major selling point because it allows you to get started with minimal effort.

In this post, we’re going to take an ASP.NET website template that uses Bootstrap 4 and set it up to use Parcel-generated bundles instead.

Create & Set Up a New ASP.NET Project

  1. Create a web project that uses Razor Pages. To do this on the command line, run:
    dotnet new webapp --name AspNetParcelExp cd AspNetParcelExp
  2. Delete the folders under wwwroot. (You may delete this later on, if you want it for reference — our goal is to generate these files using Parcel and use those instead.)
    Install npm Dependencies
  3. Add a package.json file to the project root like the following:
  4. {"name":"aspnet-parcel-exp","private":true,"version":"0.1.0"}
  1. Add parcel-bundler as a dev dependency:
  2. javascriptnpm install --save-dev parcel-bundler@1
  1. Install the libraries we deleted using npm:
  2. npm install jquery@3
    npm install popper.js@1
    npm install bootstrap@4
    npm install jquery-validation@1
    npm install jquery-validation-unobtrusive@3

    If everything went right, your package.json should look something like this:

    {"name":"aspnet-parcel-exp","private":true,"version":"0.1.0","devDependencies":{"parcel-bundler":"^1.11.0"},"dependencies":{"bootstrap":"^4.2.1","jquery":"^3.3.1","jquery-validation":"^1.19.0","jquery-validation-unobtrusive":"^3.2.11","popper.js":"^1.14.7"}}

Set Up an Asset Bundle Using Parcel.js

  1. Under the project root, create files with the following structure:
  2.  /AspNetParcelExp/ # project root
      - .sassrc       # sass configuration
      - assets/       # front end assets root
        - scss/       # Place for all styles
          - site.scss
        - js/         # Place for all scripts
          - site.js
        - bundle.js   # Entry point for our output bundle
    
  1. The bundle.js file acts as an entry point for parcel-bundler to start from. Add the following code to bundle.js:
  2. // Import styles  
    import './scss/site.scss'  
    
    // Setup jquery
    import $ from 'jquery'
    window.$ = window.jQuery = $
    
    // Import other scripts
    import 'bootstrap'  
    import 'jquery-validation'  
    import 'jquery-validation-unobtrusive'  
    
    import './js/site'
    

    We import everything we depend on. ‘bootstrap’ for example refers to the …/node_modules/bootstrap/ folder. If you want to import a specific file from a package only, you may do that too. The above code should be straightforward, except for maybe jQuery, which I’ll explain in a bit.

  1. Add the following to .sassrc:
  2.  {
      "includePaths": [
        "./node_modules/"
      ]
    }
    

    This will allow referencing package folders without a full path to it. See parcel-bundler/parcel#39 for more information.

  1. Add the following code to site.scss:
  2.  @import "~bootstrap/scss/bootstrap";
    

    You may also just include the bootstrap SCSS files that you actually need to keep the output size down. Since we’re trying to replicate the template, we could also paste the code in the original template’s site.css here after the line.

  1. Since we have no global scripts, we leave the site.js file empty for now.

  2. Add a scripts block to the package.json file right before the devDependencies: { line:

  3.  "scripts": {
      "build": "parcel build assets/bundle.js --out-dir wwwroot/dist/",
      "watch": "parcel watch assets/bundle.js --out-dir wwwroot/dist/"
    },

    This adds scripts that can be invoked as npm run build to build, for example. It passes the bundle.js entry point to Parcel, and instructs it to generate output files in the wwwroot/dist/ using the --out-dir option.

  1. Now we build our bundle:
  2. npm run build

    You should now see a bundle.css, bundle.js and a bundle.map file in the wwwroot/dist directory (the directory we specified for the build script above). It’s a good idea to ignore the wwwroot/dist from version control.

  1. We need to update all references to the old files with the new ones instead. Remove all script tags in _Layout.cshtml and _ValidationScriptsPartial and add the following instead to _Layout.cshtml:
  2. <scriptsrc="~/dist/bundle.js"asp-append-version="true"></script>
     And replace the stylesheet <link> tags with:
     <linkrel="stylesheet"href="~/dist/bundle.css"asp-append-version="true"/>

That’s it. If you did everything right, running the program should display the same output as with the old files.

If it feels like a lot of work, it’s probably because you aren’t familiar with the npm, SCSS, etc., so take your time.

Watching Changes

Rather than running npm run build each time you make changes, you can use HMR (Hot Module Replacement), which will detect pages and reload for you, so that you don’t have to do it.

Open a new terminal instance and run npm run watch. Keep this running while performing any dev changes — it’ll speed you up.

Add a Pre-Publish Task

Add the following to the AspNetParcelExp.csproj file right before the closing

</Project> tag:
<Target Name="ParcelBeforePublish" 
        BeforeTargets="PrepareForPublish">
  <Exec Command="npm run build" />
</Target>

Now, every time you create a publish package, it will run the npm build script. This is particularly important in Continuous Delivery scenarios, because the wwwroot/dist is (usually) not under version control, and the build environment needs to build the files before deploying. You may test this step using dotnet publish: you’ll see output from parcel-bundler.

If you want the task to be run every time is the project is built, change PrepareForPublish to BeforeBuild.

A Note on CommonJS Modules

The parcel-bundler generates a CommonJS module, which means it doesn’t pollute the global window object. Now this can be a problem sometimes, because some libraries — particularly the old ones — have always been polluting window.

Take jQuery for instance. Libraries that require jQuery perform a test on the window object to check if it’s got a jQuery or a $ property. Since CommonJS libraries don’t pollute window, these checks will fail. So we’ll need to manually pollute the window object ourselves. We did that for jquery in bundle.js using:

import $ from 'jquery'
window.$ = window.jQuery = $

This is one thing you need to remember when using Parcel.js or other similar bundlers.

A few pointers and ideas

  • You do not have to use SCSS. LESS or even plain CSS is completely fine.
  • Parcel.js doesn’t have a config file of its own, unlike Grunt or webpack. You may, however, have config files for each tool, and parcel-bundler will honor them. E.g. tsconfig.json for typescript, .sassrc for SCSS, etc.
  • Parce.js has built-in support for PostCSS. For example, to automatically add CSS prefixes to the generated output using the autoprefixer-postcss plugin, add the following to .postcssrc at the project root:
     { 
      "plugins": { 
        "autoprefixer": true 
      } 
    }
    
  • You can also configure the browsers you wish to support by adding a .browserslistrc file.
  • You can create multiple bundles if you want. In our example, we put all the scripts in one file, but you could configure to put the validation scripts in a separate file instead.

Understanding Telerik Fiddler as a Proxy

$
0
0

Understanding how Fiddler operates as a web debugging proxy will enable you to see what’s transmitted on the network.

Given the ubiquitous nature of the Internet, many applications are built to assume network connectivity. That’s because a connection to the web can greatly expand the capabilities of an application through the integration of remote data and services. However, this integration is often error-prone; services can become unavailable and data can take a long time to transfer over slow networks. In fact, many bugs can be attributed to conditions relating to the underlying network. In these situations, it’s useful to have a utility that’s able to help you debug the problem; a utility to monitor the network traffic (HTTP or HTTPS) that occurs between your application and the services it relies upon.

Enter Telerik Fiddler.

What is Telerik Fiddler?

Telerik Fiddler (or Fiddler) is a special-purpose proxy server for debugging web traffic from applications like browsers. It’s used to capture and record this web traffic and then forward it onto a web server. The server’s responses are then returned to Fiddler and then returned back to the client. The recorded web traffic is presented through a session list in the Fiddler UI:

Nearly all programs that use web protocols support proxy servers. As a result, Fiddler can be used with most applications without need for further configuration. When Fiddler starts to capture traffic, it registers itself with the Windows Internet (WinINet) networking component and requests that all applications begin directing their requests to Fiddler.

“What is a proxy?”

If you had asked me this question back in the early 1990s, I would have likely replied, “It’s that thing that kills your Internet connection, right?” Back in the day, if I found myself with a proxy configured on my machine then I’d sometimes see broken images on webpages. This would be followed by some cursing and many presses of the F5 key. Obviously, things have improved since then. However, the question remains a good one to ask, especially for developers writing applications that will support them.

Section 2.3 of the HTTP specification defines a proxy as:

a message-forwarding agent that is selected by the client, usually via local configuration rules, to receive requests for some type(s) of absolute URI and attempt to satisfy those requests via translation through the HTTP interface

The phrase, “selected by the client” in the description (above) is a key characteristic; a proxy is designated by a user agent (UA) to convey messages to “origin server” (i.e. google.com). It’s also specialised because it may perform actions on messages that are received. (More on this later.)

Consider this classic (and very funny) scene from the American sitcom, I Love Lucy:

In this scene, when a chocolate travels down the conveyor belt, it’s observed, picked up, wrapped, and then placed back. This is a good way of thinking about how a proxy works. Here, the assembly workers (Lucy and Ethel) represents proxies, a chocolate represents a message, and the conveyor belt represents the network. It’s a brilliant scene because the concepts of network latency and reliability are also personified.

This scene doesn’t represent a network in all its aspects. For example, it only represents outbound traffic. Let’s not forget that HTTP is a request-response protocol. What about inbound traffic? For this, we would have to imagine chocolates simultaneously travelling in the opposite direction. The assembly worker would modify and forward the chocolates in the same manner as before. When this occurs with a network, a proxy is defined as a “reverse proxy” or “gateway.” In other words, an origin server for outbound messages; it translates requests and forwards them inbound.

Telerik Fiddler as a Proxy

Fiddler is a web debugging proxy. That means it acts as an intermediary and can troubleshoot the traffic that’s sent between a user agent (i.e. Google Chrome) and the network.

As mentioned above, nearly all programs that use web protocols support integration with a proxy, and Fiddler can be used with most applications without the need for further configuration.

In the most common scenario where Fiddler is the only proxy that’s configured to operate on the network, the architecture becomes a little simpler:

Many web developers will use Fiddler in this manner; to record web traffic that’s generated by a browser to see what was transmitted. Since Fiddler is a proxy, it may process this web traffic before forwarding it upstream. This includes responding to messages on behalf of the origin server. The HTTP specification enables proxies to do this. In fact, Fiddler can be configured to respond to messages that match criteria you define through the AutoResponder. The feature may be configured to serve local files (acting as a cache) or perform actions for messages it receives:

The AutoResponder supports a useful development scenario when resources and/or services may be unavailable. It may be used to mock API responses from a service. The AutoResponder may also be configured with a latency setting to simulate a more realistic response time.

The HTTP specification enables proxies to transform messages and their payloads (see section 5.7.2). In the example I cited (above), this is represented by Lucy and Ethel wrapping the individual chocolates as they travel along the conveyor belt. Fiddler is capable of transforming messages as they are intercepted. For example, I can add/remove HTTP headers and modify message payloads.

The transformation of messages is made possible through custom rules written in FiddlerScript. FiddlerScript is one of the most powerful features in Fiddler; it can be used to enhance Fiddler’s UI, add new features, and modify messages. It can even change various characteristics of the network or client as messages are transmitted. For example, I can write FiddlerScript to simulate conditions of the browser (i.e. no cookies) or reroute traffic.

Eric Lawrence has written a great article, Understanding FiddlerScript, where he describes its available functions. He’s also published a list of FiddlerScript “recipes”: Fiddler Web Debugger - Script Samples.

The More You Know

Understanding how Fiddler operates as a web debugging proxy will enable you to target scenarios where you’re interested in seeing what’s transmitted on the network. Once you have Fiddler configured correctly, you’ll be able to use its large set of features. To get started, why not download Fiddler and kick the tires for yourself? And if you’re interested in seeing the future, check out Fiddler Everywhere, which runs across Windows, macOS, and Linux.

Using Polly for .NET Resilience and Transient-Fault-Handling with .NET Core

$
0
0

Learn how the Polly Project, an open source .NET framework that provides patterns and building blocks for fault tolerance and resilience in applications, can be used with .NET Core.

Error handling and resuming reliably in case of an error are the Achilles’ heel of many software projects. Applications that were running smoothly all along suddenly turn into chaotic nightmares as soon as network connectivity stutters or disk space depletes. Professional software stands out by dealing with exactly those edge cases (at a certain adoption rate, those “edge cases” even become normality), expecting them and handling them gracefully. Being able to rely on an existing and battle-hardened framework for such scenarios makes things even easier.

Enter Polly

This is where The Polly Project comes into play. Polly is an open source .NET framework that provides patterns and building blocks for fault tolerance and resilience in applications.

the-polly-project

The Polly Project Website

Polly is fully open source, available for different flavors of .NET starting with .NET 4.0 and .NET Standard 1.1 and can easily be added to any project via the Polly NuGet package. For .NET Core applications this can be done from the command line using the dotnet CLI command.

dotnet add package Polly

Or by adding a PackageReference to the .csproj file (at the time of writing, the latest version was 6.1.2).

<PackageReference Include="Polly" Version="6.1.2" />

When using Visual Studio, “Manage NuGet Packages…” is the quickest way to go.

polly-nuget-vs

Adding the Polly NuGet Reference in Visual Studio

Now that Polly has been added to the project, the question arises: How and in which scenarios can it be used? As is so often the case, this is best explained using actual code and a practical example.

To keep things relatively simple, let’s assume we have an application that persists data or settings continuously in the background by writing them to disk. This happens in a method called PersistApplicationData.

private void PersistApplicationData()

Since this method is accessing the file system, it’s more or less bound to fail from time to time. The disk could be full, files could be locked unexpectedly by indexing services or anti-virus software, access rights might have been revoked... basically anything could happen here. File system access should always be treated as an external dependency that’s out of an application’s control. Therefore, as a basic minimum, a try catch block is required.

The next obvious question is what kinds of exceptions should be caught in the catch block? Going for the Exception base class covers all possible cases, but it also might be too generic. Exceptions like NullReferenceException or AccessViolationException usually imply severe problems in the application’s logic and should probably not be handled gracefully. So catching specific exceptions like IOException or InvalidOperationException might be the better option here. Hence, we end up with two catch blocks for this example.

Since we don’t want to completely ignore those exceptions, at least some logging code needs to be put in place. So we need to duplicate a call to some logging method in the catch blocks.

As a next step, we have to to think about whether or how the application should continue in case an actual exception has occurred. If we assume that we want to implement a retry pattern, an additional loop outside the try catch block is required to be able to repeat the call to PersistApplicationData. This can either be an infinite loop or a loop that terminates after a specific number of retries. In any case, we manually need to make sure that the loop is exited in case of a successful call.

Last but not least we should also consider that the likelihood of failure is really high if a subsequent call to PersistApplicationData happens again immediately. Some kind of throttling mechanism is probably required. The most basic way to do that would be a call to Thread.Sleep using a hard-coded number of milliseconds. Or we could use an incremental approach by factoring in the current loop count.

Putting all these considerations in place, a simple method call quickly turned into a 20+ line construct like this.

private void GuardPersistApplicationData()
{
  const int RETRY_ATTEMPTS = 5;
  for (var i = 0; i < RETRY_ATTEMPTS; i++) {
    try
    {
      Thread.Sleep(i * 100);
      // Here comes the call, we *actually* care about.
      PersistApplicationData(); 
      // Successful call => exit loop.
      break;
    }
    catch (IOException e)
    {
      Log(e);
    }
    catch (UnauthorizedAccessException e)
    {
      Log(e);
    }
  }
}

This simple example illustrates the core problem when it comes to fault-tolerant and resilient code: It’s often not pretty to look at and even hard to read because it obscures the actual application logic.

Resilient and fault-tolerant code is necessary... but not always “pretty” to look at.

The obvious solution to that problem are generically reusable blocks of code that handle those identified concerns. Instead of reinventing the wheel and writing these blocks of codes again and again, a library like Polly should be our natural weapon of choice.

Polly provides building blocks for exactly those use cases (and many more) we identified before in the form of policies. So let’s take a look at these policies in more detail and how they can be used for the example above.

Retry Forever

The most basic Policy that Polly provides is RetryForever, which does exactly what its name suggests. A specific piece of code (here: PersistApplicationData) is executed over and over again until it succeeds (i.e. it does not throw an exception). The policy is created and applied by defining the expected exceptions first via a call to Policy.Handle. Then RetryForever specifies the actual policy used and Execute expects the code which will be guarded by the policy.

Policy.Handle<Exception>()
  .RetryForever()
  .Execute(PersistApplicationData);

Again, we don’t want to generically handle all possible exceptions but rather specific types. This can be done by providing the according type arguments and combining them using the Or method.

Policy.Handle<IOException>().Or<UnauthorizedAccessException>()
  .RetryForever()
  .Execute(PersistApplicationData);

Consequently, catching those exceptions silently is really bad practice, so we can use an overload of RetryForever that expects an expression which gets called in case of an exception.

Policy.Handle<IOException>().Or<UnauthorizedAccessException>()
  .RetryForever(e => Log(e.Message))
  .Execute(PersistApplicationData);

Retry n Times

The RetryForever policy already covered a part of the requirements we identified initially, but the concept of a potentially infinite number of calls to PersistApplicationData is not what we had in mind. So we could opt for the Retry policy instead. Retry behaves very similar to RetryForever with the key difference that it expects a numeric argument which specifies the actual number of retry attempts before it gives up.

Policy.Handle<Exception>()
  .Retry(10)
  .Execute(PersistApplicationData);

Similarly, there is also an overload of Retry that allows the caller to handle an eventual exception and additionally receives an int argument specifying how many times the call has already been attempted.

Policy.Handle<Exception>()
  .Retry(10, (e, i) => Log($"Error '{e.Message}' at retry #{i}"))
  .Execute(PersistApplicationData);

Wait and Retry

The last requirement that is still unfulfilled from the initial example is the possibility to throttle the execution of the retry mechanism, hoping that the flaky resource which originally caused this issue might have recovered by now.

Again, Polly provides a specific policy for that use case called WaitAndRetry. The simplest overload of WaitAndRetry expects a collection of Timespan instances and the size of this collection implicitly dictates the number of retries. Consequently, the individual Timespan instances specify the waiting time before each Execute call.

Policy.Handle<Exception>()
  .WaitAndRetry(new [] { TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(200) })
  .Execute(PersistApplicationData);

If we wanted to calculate those wait times dynamically, another overload of WaitAndRetry is available.

Policy.Handle<Exception>()
  .WaitAndRetry(5, count => TimeSpan.FromSeconds(count))
  .Execute(PersistApplicationData);

An infinite amount of retries using a dynamic wait time is also possible by using WaitAndRetryForever.

Policy.Handle<Exception>()
  .WaitAndRetryForever(count => TimeSpan.FromSeconds(count))
  .Execute(PersistApplicationData);

Circuit Breaker

The last policy we want to take a look at is slightly different from those we got to know so far. CircuitBreaker acts like its real-world prototype, which interrupts the flow of electricity. The software counterpart of fault current or short circuits are exceptions, and this policy can be configured in a way that a certain amount of exceptions “break” the application’s flow. This has the effect that the “protected” code (PersistApplicationData) simply will not get called any more, as soon as a given threshold of exceptions has been reached. Additionally, an interval can be specified, after which the CircuitBreaker recovers and the application flow is restored again.

Because of that pattern, this policy is usually used by setting it up initially and storing the actual Policy instance in a variable. This instance keeps track of failed calls and the recovery interval and is used to perform the Execute call in a different place.

  .Handle<IOException>().Or<UnauthorizedAccessException>()
  .CircuitBreaker(5, TimeSpan.FromMinutes(2));
  // ...
  policy.Execute(PersistApplicationData);

But Wait, There’s More!

The policies demonstrated above offer only a small peek into the versatile functionality that Polly provides. Each of these policies is e.g. also available in an Async flavor (RetryForeverAsync, RetryAsync, WaitAndRetryAsync, CircuitBreakerAsync) while still providing that same ease of use as the synchronous counterpart.

Just the CircuitBreaker policy alone offers multiple additional ways of configuration which are documented in detail on the GitHub repository. In general, this repository, its documentation and the samples are a great starting point for learning about the policies provided by Polly and the core concepts of resilience and transient-fault-handling. Hopefully, it serves as an inspiration to get rid of custom, hand-crafted error handling code, or even better, it helps to avoid writing that kind of code in future projects and use the powers of Polly instead.

View PDF Documents with PdfViewer for Xamarin.Forms

$
0
0

Viewing PDF documents in your mobile app without the need to install a third-party solution has never been easier. Now you can use the Telerik UI for Xamarin PdfViewer control within your application. PdfViewer control comes with a number of features for viewing and manipulating PDF files. 

We have received many requests from our customers to create a component that will provide them with the best user experience when working with PDF documents, and we were happy to introduce a control for this in the official R1 2019 release of Telerik UI for Xamarin. Since that time we have focused on improving it further based on the feedback received from our users. A new set of features was introduced in February with the release of the Service Pack

In this blog post you will learn more about the PdfViewer control for Xamarin.Forms. You will also learn about the new features coming with it and how to use them.


PdfViewer Overview

Features

  • Visualize pdf documents - Display PDF documents with text, images, shapes (geometrics), different colors (solid, linear and radial gradients), ordered and bullet lists, and more
  • Various document source options - You could load the PDF document from a stream, from a file added as embedded resource or a file located on the device, etc.
  • Zooming Functionality with min and max zoom lever support
  • Single Page and Continuous Scrolling Support  for displaying one page at a time or displaying all pages continuously in the viewer
  • Commands Support for Zooming, Navigating from page to page, FitToWidth or Toggling the Layout mode
  • Toolbar Support with pre-defined UI toolbar items including all PdfViewer commands

Let’s get a deeper insight into the features listed above.

Various Document Source Options

PdfViewer enables you to visualize PDF documents through its Source property. The documents could be loaded from various document sources like:

  • FileDocument
  • Uri
  • ByteArray
  • Stream
  • FixedDocument

For example, lets take a look at the FileDocumetSource, FixedDocumentSource and UriDocumentSource:

The FileDocumentSouce has become part of the PdfViewer features set with the Telerik UI for Xamarin R1 2019 Service Pack. It allows you to load a PDF document from a file stored on the device. For example:

<telerikpdfviewer:radpdfviewer x:name="pdfViewer" source="{Binding FilePath}"></telerikpdfviewer:radpdfviewer>

where FilePath is a string property in the ViewModel:

string FilePath {get;}

When using the FileDocumentSource, please make sure that you have granted the app all the permissions needed before the resources are used. Otherwise, an exception will be raised.

Load a PDF document as embedded resources using FixedDocumentSource:

<telerikpdfviewer:radpdfviewer x:name="pdfViewer"></telerikpdfviewer:radpdfviewer>
Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider provider = new Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider();
Assembly assembly = typeof(KeyFeatures).Assembly;
string fileName = assembly.GetManifestResourceNames().FirstOrDefault(n => n.Contains("pdfName.pdf"));
using (Stream stream = assembly.GetManifestResourceStream(fileName))
{
   RadFixedDocument document = provider.Import(stream);
   this.pdfViewer.Source = new FixedDocumentSource(document);
}
Visualizing PDF documents from Uri:
Uri uri = new Uri("https://....../pdfName.pdf");
this.pdfViewer.Source = uri;

Commands Support

PdfViewer exposes the following commands

  • ZoomInCommand
  • ZoomOutCommand
  • FitToWidthCommand
  • NavigateToNextPageCommand
  • NavigateToPreviousPageCommand
  • NavigateToPageCommand
  • ToggleLayoutModeCommand

For more information how to use them check our help article.

When a new document is loaded, it is automatically adjusted to fit the current width for the best viewing experience. It means that the FitToWidth command is executed when the document is loaded. 

PdfToolbar Support with Built-In Commands Operations

All the commands that PdfViewer provides are included in the PdfToolbar. This feature allows you and the end user of the application to use the commands much more easily with the predefined UI. You only need to decide which ones you need in the application depending on the requirements you have.

All you need to do is to choose the commands and include them as a PdfViewerToolbar items. For example:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <telerikPdfViewer:RadPdfViewerToolbar PdfViewer="{Binding Source={x:Reference pdfViewer}}">
        <telerikPdfViewer:ZoomInToolbarItem />
        <telerikPdfViewer:ZoomOutToolbarItem />
        <telerikPdfViewer:NavigateToNextPageToolbarItem/>
        <telerikPdfViewer:NavigateToPreviousPageToolbarItem/>
        <telerikPdfViewer:NavigateToPageToolbarItem/>
        <telerikPdfViewer:FitToWidthToolbarItem/>
        <telerikPdfViewer:ToggleLayoutModeToolbarItem/>
    </telerikPdfViewer:RadPdfViewerToolbar>
    <telerikPdfViewer:RadPdfViewer x:Name="pdfViewer" Grid.Row="1"/>
</Grid>

The image below shows what the PdfViewer Toolbar looks like:

PdfToolbar

Have we caught your interest with the new PdfViewer control and its features? You can find various demos of the new control in ourSDK Samples Browser and a First Look example with  PdfToolbar in the Telerik UI for Xamarin Demo application.

The control is still in beta and we are actively working on adding new features and making it official for the upcoming Telerik UI for Xamarin R2 2019 Official Release. So, any feedback on it is highly appreciated, as always. If you have any ideas for features to add to the control’s features set, do not hesitate to share this information with us on our Telerik UI for Xamarin Feedback portal.

If this is the first time you're hearing about Telerik UI for Xamarin, you can find more information about it on our website or dive right into a free 30-day trial today.


How to Port Desktop Applications to .NET Core 3.0

$
0
0

In this post, Olia Gavrysh (Program Manager, Microsoft) guides you through the process of porting a desktop application from .NET Framework to .NET Core using an existing WinForms application as an example.

This article was originally posted on the Microsoft .NET Blog and is republished with permission.

In this post, I will describe how to port a desktop application from .NET Framework to .NET Core. I picked a WinForms application as an example. Steps for WPF application are similar and I’ll describe what needs to be done different for WPF as we go. I will also show how you can keep using the WinForms designer in Visual Studio even though it is under development and is not yet available for .NET Core projects.

About the sample

For this post, I’ll be using a Memory-style board game application. It contains a WinForms UI (MatchingGame.exe) and a class library with the game logic (MatchingGame.Logic.dll), both targeting .NET Framework 4.5. You can download the sample here. I’ll be porting the application project to .NET Core 3.0 and the class library to .NET Standard 2.0. Using .NET Standard instead of .NET Core allows me to reuse the game logic to provide the application for other platforms, such as iOS, Android or web.

You can either watch Scott Hunter and me doing the conversion in the following video, or you can follow the step-by-step instructions below. Of course, I won’t be holding it against you, if you were to do both.

Step-by-step process

I suggest doing the migration in a separate branch or, if you’re not using version control, creating a copy of your project so you have a clean state to go back to if necessary.

Before porting the application to .NET Core 3.0, I need to do some preparation first.

Preparing to port

  1. Install .NET Core 3 and Visual Studio 2019 Preview version (Visual Studio 2017 only supports up to .NET Core 2.2).
  2. Start from a working solution. Ensure the solution opens, builds, and runs without any issues.
  3. Update NuGet packages. It’s always a good practice to use the latest versions of NuGet packages before any migration. If your application is referencing any NuGet packages, update them to the latest version. Ensure your application builds successfully. In case of any NuGet errors, downgrade the version and find the latest one that doesn’t break your code.
  4. Run the .NET Portability Analyzer to determine if there are any APIs your application depends on that are missing from .NET Core. If there are, you need to refactor your code to avoid dependencies on APIs, not supported in .NET Core. Sometimes it’s possible to find an alternative API that provides the needed functionality.
  5. Replace packages.config with PackageReference. If your project uses NuGet packages, you need to add the same NuGet packages to the new .NET Core project. .NET Core projects support only PackageReference for adding NuGet packages. To move your NuGet references from packages.config to your project file, in the solution explorer right-click on packages.config -> Migrate packages.config to PackageReference….You can learn more about this migration in the Migrate from packages.config to PackageReference article.

Porting main project

Create new project

  1. Create new application of the same type (Console, WinForms, WPF, Class Library) as the application you are willing to port, targeting .NET Core 3. At the moment we did the demo Visual Studio templates for desktop projects were under development, so I used the console.
    dotnet new winforms -o <path-to-your-solution>\MatchingGame.Core\</path-to-your-solution>
  2. In the project file copy all external references from the old project, for example: 
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
  3. Build. At this point if the packages you’re referencing support only .NET Framework, you will get a NuGet warning. If you have not upgraded to the latest versions of NuGet packages on the step 3, try to find if the latest version supporting .NET Core (.NET Standard) is available and upgrade. If there are no newer version, .NET Framework packages can still be used but you might get run-time errors if those packages have dependencies on APIs not supported in .NET Core. We recommend to let the author of the NuGet package know that you’d be interested in seeing the package being updated to .NET Standard. You can do it via Contact form on the NuGet gallery.

Fast way (replace existing project file)

First, let’s try the fast way to port. Make sure you have a copy of your current .csproj file, you might need to use it in future. Replace your current .csproj file with the .csproj file from the project you created on the step above and add in the top <PropertyGroup>:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Build your app. If you got no errors – congrats, you’ve successfully migrated your project to .NET Core 3. For porting a dependent (UI) project see Porting UI section, for using the Designer, check out Using WinForms Designer for .NET Core projects section.

Slow way (guided porting)

If you got errors (like I did with my app), it means there are more adjustments you need to make. Instead of the fast way described above, here I’ll do one change at a time and give possible fixes for each issue. Steps bellow would also help to better understand the process of the migration so if the fast way worked for you but you’re curious to learn all “whys”, keep on reading.

  1. Migrate to the SDK-style .csproj file. To move my application to .NET Core, first I need to change my project file to SDK-style format because the old format does not support .NET Core. Besides, the SDK-style format is much leaner and easier to work with.Make sure you have a copy of your current .csproj file. Replace the content of your .csproj file with the following. For WinForms application:
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net472</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
      </PropertyGroup>
    </Project>

    For WPF application:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net472</TargetFramework>
        <UseWPF>true</UseWPF>
        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
      </PropertyGroup>
    </Project>

    Note that I set <GenerateAssemblyInfo> to false. In the new-style projects AssemblyInfo.cs is generated automatically by default. So if you already have AssemblyInfo.cs file in your project (spoiler alert: you do), you need to disable auto-generation or remove the file.

    Now copy & paste all references from the old version of .csproj file into the new one. For example:

    NuGet package reference

    <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.1" />

    Project reference

    <ProjectReference Include="..\MatchingGame.Core\MatchingGame.Core.csproj" />

    The project should build successfully since it is just a new way of writing the same thing. If you got any errors, double check your steps.

    There is also a third-party tool CsprojToVs2017 that can perform the conversion for you. But after using it, you still might need to delete some reference by hand, such as:

    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Net.Http" />
  2. Move from .NET Framework to .NET Standard or .NET Core. After successfully converting my library to SDK-style format I’m able to retarget it. In my case I want my class library to target .NET Standard instead of .NET Core. That way, it will be accessible from any .NET implementation if I decide to ship the game to other platforms (such as iOS, Android, or Web Assembly). To do so, replace this
    <TargetFramework>net472</TargetFramework>

    with

    <TargetFramework>netstandard2.0</TargetFramework>

    Build your application. You might get some errors if you are using APIs that are not included in .NET Standard. If you did not get any errors with your application, you can skip the next two steps.

  3. Add Windows Compatibility Pack if needed. Some APIs that are not included in .NET Standard are available in Windows Compatibility Pack. If you got errors on the previous step, you can check if Windows Compatibility Pack can help.I got an error “The name ‘Registry’ does not exist in the current context”, so I added the Microsoft.Windows.Compatibility NuGet package to my project. After installation, the error disappeared.
  4. Install API AnalyzerAPI Analyzer, available as the NuGet package Microsoft.DotNet.Analyzers.Compatibility, will prompt you with warnings when you are using deprecated APIs or APIs that are not supported across all platforms (Windows, Linux, macOS). If you added the Compatibility Pack, I recommend adding the API Analyzer to keep track of all of API usages that won’t work across all platforms.At this point, I am done with the class library migration to .NET Standard. If you have multiple projects referencing each other, migrate them “bottom-up” starting with the project that has no dependencies on other projects.In my example I also have a WinForms project MatchingGame.exe, so now I will perform similar steps to migrate that to .NET Core.

Porting the UI

  1. Add .NET Core UI project. Add a new .NET Core 3.0 UI project to the solution. At this moment, the Visual Studio templates for desktop projects are under development, so I just used the dotnet CLI.
    dotnet new winforms -o <path-to-your-solution>\MatchingGame.Core\

    For WPF projects you’d use this:

    dotnet new wpf -o <path-to-your-solution>\MatchingGame.Core\

    After my new WinForms .NET Core project was created, I added it to my solution.

  2. Link projects. First, delete all files from the new project (right now it contains the generic Hello World code). Then, link all files from your existing .NET Framework UI project to the .NET Core 3.0 UI project by adding following to the .csprojfile. 
    <ItemGroup>
        <Compile Include="..\<Your .NET Framework Project Name>\**\*.cs" />
        <EmbeddedResource Include="..\<Your .NET Framework Project Name>\**\*.resx" />
    </ItemGroup>

    If you have a WPF application you also need to include .xaml files: 

    <ItemGroup>
      <ApplicationDefinition Include="..\WpfApp1\App.xaml" Link="App.xaml">
        <Generator>MSBuild:Compile</Generator>
      </ApplicationDefinition>
      <Compile Include="..\WpfApp1\App.xaml.cs" Link="App.xaml.cs" />
    </ItemGroup>
      
    <ItemGroup>
      <Page Include="..\WpfApp1\MainWindow.xaml" Link="MainWindow.xaml">
        <Generator>MSBuild:Compile</Generator>
      </Page>
      <Compile Include="..\WpfApp1\MainWindow.xaml.cs" Link="MainWindow.xaml.cs" />
    </ItemGroup>
  3. Align default namespace and assembly name. Since you’re linking to designer generated files (for example, Resources.Designer.cs), you generally want to make sure that the .NET Core version of your application uses the same namespace and the same assembly name. Copy the following settings from your .NET Framework project:
    <PropertyGroup>
        <RootNamespace><!-- (Your default namespace) --></RootNamespace>
        <AssemblyName><!-- (Your assembly name) --></AssemblyName>
    </PropertyGroup>
  4. Disable AssemblyInfo.cs generation. As I mentioned earlier, in the new-style projects, AssemblyInfo.cs is generated automatically by default. At the same time the AssemblyInfo.cs file from the old WinForms project will be copied to the new project too, because I linked all files **\*.cs in the previous step. That will result in duplication of AssemblyInfo.cs. To avoid it in MatchingGame.Core project file I set GenerateAssemblyInfo to false.
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  5. Run new project. Set your new .NET Core project as the StartUp project and run it. Make sure everything works.
  6. Copy or leave linked. Now instead of linking the files, you can actually copy them from the old .NET Framework UI project to the new .NET Core 3.0 UI project. After that, you can get rid of the old project.

Using the WinForms designer for .NET Core projects

As I mentioned above, the WinForms designer for .NET Core projects is not yet available in Visual Studio. However there are two ways to work around it:

  1. You can keep your files linked (by just not performing the previous step) and copy them when the designer support is available. This way, you can modify the files in your old .NET Framework WinForms project using the designer. And the changes will be automatically reflected in the new .NET Core WinForms project — since they’re linked.
  2. You can have two project files in the same directory as your WinForms project: the old .csproj file from the existing .NET Framework project and the new SDK-style .csproj file of the new .NET Core WinForms project. You’ll just have to unload and reload the project with corresponding project file depending on whether you want to use the designer or not.

Summary

In this blog post, I showed you how to port a desktop application containing multiple projects from .NET Framework to .NET Core. In typical cases, just retargeting your projects to .NET Core isn’t enough. I described potential issues you might encounter and ways of addressing them. Also, I demonstrated how you can still use the WinForms designer for your ported apps while it’s not yet available for .NET Core projects.


Looking for More Info on Telerik Products and .NET Core 3.0?


We hope you enjoyed reading Olia's post. We on the Progress Telerik team are excited about .NET Core 3.0, and for those of you out there using Telerik UI for WinForms or Telerik UI for WPF, we'd like to remind you that the controls in both products are .NET Core 3.0 compatible. If you want to test it out on your applications, check out this blog post for more info. Happy coding!

How to: Test Your API with Fiddler

$
0
0

In part 1 and part 2 of this Fiddler how-to series, we covered the basics of the Composer tab and how it makes your life better. Now to the best part – automation.

Manually testing API calls is OK when we're initially developing the service. But what about when we change something? Should we execute all these requests again, one by one, and verify the responses? Or even worse, go through the UI and click every single button again? No! Fiddler has got you covered here. Again.

The API Test Fiddler extension greatly enhances its power to execute and validate the behavior of web APIs. Just go to View> Tabs> APITest to show the APITest tab.

api

Creating a Test

You can create a new test by simply dragging and dropping sessions from Fiddler’s Sessions list. You can then use the context menu to specify a Validator and optionally mark it with a Note (comment) or assign it to a group.

Setting a Validator

With validators you can specify if a test is success or failure. Fiddler supports the following validator types:

  • EXACT: Ensures that body contains (case-sensitively) the text
  • REGEX: Ensures that body matches the text
  • NOT: Ensures that body doesn’t contain the text
  • {CODE}: Ensures that the response status code matches the original status.
  • {BODY}: Ensures that body is identical
  • HEADER: Ensures that the response bears a specified header containing a given value
  • SCRIPT: This prefix allows you to specify a FiddlerScript function in your CustomRules.js file to use to evaluate the response

Working with Test Lists

Test List is a set of Sessions that contain several specific session flags. They can be easily exported as a SAZ files and their “Test List” functionality will only light up when loaded into the APITest tab. This functionality is available through the contextual menu.

api-2

Disabling Tests

You can temporarily disable one or more tests from running by pressing the spacebar with the desired tests selected.

FiddlerScript Events

Fiddler supports two test list events that can be used:

  • BeforeTestList: Fires before the Test List is executed
  • AfterTestList: Fires after all of the tests in the Test List are executed

Conclusion

Telerik Fiddler’s APITest tab can help you test your REST APIs with ease, allowing you to make sure you maintain good quality, even when changes are made.

P.S. Don’t forget to follow us on Twitter to get the latest news, tips and tricks and more

Xamarin.Forms: Recurring Appointments and Built-in Scheduling Dialogs in Calendar

$
0
0

With the recent R1 2019 release of the Telerik UI for Xamarin suite we have added a couple of much-requested functionalities to the Xamarin Calendar control – recurring appointments and built-in scheduling pages.

This blog post will give you a brief overview of the features and the control’s new awesome capabilities which can help you integrate a great scheduling experience within your Xamarin based mobile app in a matter of minutes. 

Recurring Appointments

First, lets have a look at the newly introduced recurrence support for the calendar’s appointments. In order to take advantage of the recurring engine, we have introduced a new Appointment class which we recommend you use instead of creating a custom appointment that implements the IАppointment interface (which was the approach we suggested prior to this release). The RadCalendar control will still work with the old setup, however, scheduling and recurrence will not be supported in such a case.

So, what does this Appointment class provide beyond the interface? It exposes an additional property – RecurrenceRule which is of type IRecurrenceRule. At this point, you might be wondering, “you want me to change my current setup to use the Appointment class just for one additional property?”, but do not let this small difference mislead you. Beneath the fragile shell of just another POCO property lies a powerful scheduling mechanism which you can twist around in order to achieve even the most complex rules for a recurring event. Simply review the RecurrencePattern capabilities and come up with a mix of settings which suit your needs. Let’s briefly look at the options you have to control the recurrence:

  • Frequency– Lets you decide the period on which the appointment will appear, can be daily, weekly, monthly, yearly.
  • Interval– the interval on which the appointment will appear – e.g. every 2 days, every 3 months, etc.
  • DaysOfWeekMask– a flag enum where you can explicitly point out the days on which the event will occur – e.g on Tuesday, on Wednesday and Friday, on every weekend day.
  • DaysOfMonth – a collection of all days in the month on which the appointment should occur.
  • DayOrdinal – lets you specify the day ordinal – e.g the first Sunday, the second Monday.
  • MonthOfYear – the particular month within the year when the event will happen.

You can also control the number of appearances or the date until which the event will appear by setting the MaxOccurrences (exact number of occurrences) or RepeatsUntil (a specific date) properties.

Here is how easy it is to add a recurring appointment to your calendar:

Create a collection of Appointments (you can inherit from the Appointment class as well) and set it as the AppointmentsSource of your RadCalendar instance:

DateTime time = DateTime.Parse("1:00");
this.Source = newObservableCollection<Appointment>()
{
    newAppointment()
    {
        StartDate = time,
        EndDate = time.AddHours(1),
        Color = Color.Orange,
        RecurrenceRule = rule,
        Title = "Recurring",
        IsAllDay = false
    }
};

Where the RecurrenceRule is defined as follows:

RecurrenceRule rule = newRecurrenceRule(newRecurrencePattern()
{
    Frequency = RecurrenceFrequency.Daily,
    Interval = 2,
    MaxOccurrences = 5
});

Make sure the calendar’s AppointmentsSource is bound to the collection from your ViewModel or class that is used as a binding context, and run the application on any platform:

appointments

Scrolling the Multi-day view to the next page shows that the appointment is limited to five occurrences only:

appointments_next

The RecurrenceRule class also supports adding exceptions to the rules, which is useful for a single appointment whose properties differ from those of the series or when you want to remove the appointment for a specific date. The latter is achieved by adding a single exception to the already created rule:

RecurrenceRule rule = newRecurrenceRule(newRecurrencePattern()
{
    Frequency = RecurrenceFrequency.Daily,
    Interval = 2,
    MaxOccurrences = 5
});
rule.Exceptions.Add(newExceptionOccurrence() { ExceptionDate = time.AddDays(2) });

Here is the modified appearance:
exception_date

Adding a specific appointment as exception is also straightforward. You just specify the date and add a new Appointment which will substitute for the default one:

RecurrenceRule rule = newRecurrenceRule(newRecurrencePattern()
{
    Frequency = RecurrenceFrequency.Daily,
    Interval = 2,
    MaxOccurrences = 5
});
 
var exceptionDate = time.AddDays(2);
rule.Exceptions.Add(newExceptionOccurrence() { ExceptionDate = exceptionDate, Appointment = newAppointment() {
    StartDate = exceptionDate.AddHours(2),
    EndDate = exceptionDate.AddHours(4),
    Color = Color.DarkGreen,
    Title = "Exception",
    IsAllDay = false
} });

Here is the result:

Exception_appointment

Built-in Scheduling

The second major feature that we shipped with R1 2019 is directly related to the scheduling capabilities of the Xamarin Calendar that we discussed in the previous paragraph. We have introduced built-in scheduling pages for creating appointments and modifying their properties, including their recurrence rule. Just setting the SchedulingUIEnabled property of the RadCalendar to "true" enables the functionality for your users. They can add new appointments and edit or delete already existing ones.

appointments_dialogs

You can control whether to show the windows for specific time slots or Appointments that were tapped by subscribing to the TimeSlotTapped/AppointmentTapped events and setting their e.Handled arguments. This is particularly useful in case you would like to disable the feature according to specific criteria or would like to show custom add/edit windows.

Try it Out and Share Your Feedback

You can have a more detailed look and test the experience with the default scheduling views by checking the available calendar/scheduling demos in our QSF and SDK Samples applications or by directly downloading the demo apps from the different platform stores – iOS, Android or Microsoft.

As you can see, there are a lot of useful properties to control the scheduling of the RadCalendar element and the different combinations provide you with numerous possibilities to fulfill your users’ demands. Still, if you are having difficulties achieving a specific scenario – do not hesitate to reach out to us either by raising a ticket or writing in the Telerik UI for Xamarin official forum.

In the upcoming releases we will keep working on improving the features and performance of the Calendar control, so any feedback from your side is highly appreciated - just let us know what features you would like to see on our Progress Telerik UI for Xamarin Feedback Portal. Lastly, if you haven't gotten a chance to try the latest version of the suite, you can do so by downloading a fresh trial from the Telerik UI for Xamarin Product Page.

Telerik UI for Blazor 0.3.0 is Released

$
0
0

Telerik UI for Blazor 0.3.0 was released last week. Along with new components and features, this new release is compatible with Visual Studio 2019 preview 3, ASP.NET Core 3.0 preview 3, and Blazor 0.9.0.

We're proud to announce our 3rd release of our early preview for Blazor. The early preview is intended to give developers a peek into our development process of UI components while giving everyone a chance to share their feedback on the product. We are working closely to align our goals with those of Microsoft's by keeping pace with their release schedule. This new version aligns our UI components with the ASP.NET Core 3.0 preview 3, and Blazor 0.9.0 release.

Telerik UI for Blazor is now compatible with:

  • Visual Studio 2019 Preview 3
  • ASP.NET Core 3.0 Preview 3
  • and Blazor 0.9.0

What's New

In this release we've added several new components, written from scratch, for Blazor and Razor Components. Our plan is to continue creating more components with native Blazor framework technologies and no legacy JavaScript dependencies. Of course, existing components are getting plenty of features added as well.

The Grid Gets New Features

We know many of you are relying on a powerful data grid (alternatively: data table) in many of your applications. This is why it is receiving a lot of our attention as we are building out Telerik UI for Blazor. With this release the UI for Blazor data Grid received some updates specifically around editing, namely:

Inline Editing

Telerik UI for Blazor data Grid with first row in edit mode

As the name might give away, or if you're familiar with this feature in other Telerik data grids, this feature allows users to put an entire row in edit mode by clicking on a built-in "edit" button.

Popup Editing

Telerik UI for Blazor data Grid with modal popup window editing a single row

Popup editing provides a modal window that contains all of the relative input elements to edit a particular row, giving users another way to update a single row of data at a time.

As I know this might pop up as well: Yes, we also support in-cell editing in the Telerik UI for Blazor Grid! This received some fixes for the 0.3.0 release, but has been available for a while.

Editor Templates

Telerik UI for Blazor data Grid in edit mode with drop down list editing the first field

While the Telerik UI for Blazor Grid does have some standard editors (the components that automatically appear) when you provide a data model, at this point we are a bit limited as we do not have all of the editors that we want (yet). Rather than wait until we release all form elements we wanted to give developers a chance to customize what is used to edit a particular field, which leads us to editor templates. You can now define a template for each particular column in a data table to ensure that the proper UI component is used to interact with that particular field.

New Component: The NumericTextBox

 

Two Telerik UI for Blazor Numeric Text Boxes. One with a built-in percentage format and the other with a custom kg format

The NumericTextBox is a great little input component to use whenever a number is used - no matter what the format is! We have a few built-in formats (like percentage and decimal for example), but you can also provide your own custom format to display in the component.

New Component: The Window

A Telerik UI for Blazor Window component with two inputs listed internally to edit first and last names

The Window provides us with an intuitive way to display additional information in a popup that can be moved around the page. It comes with built-in features like expand and minimize, close and open, as well as the ability to define custom actions.

Official Documentation Released

You may have noticed this already, but with the Telerik UI for Blazor 0.3.0 release we also officially released our documentation!

Stay Tuned for More Blazor News!

We're committed to Telerik UI for Blazor and plan to continue this cadence of frequent releases to ensure that you, the developer, can follow the evolution of our set of UI components for Blazor. We're also planning on releasing more content in the form of videos, blogs, and samples to make it even easier to dive in and pick up Telerik UI for Blazor. If you're watching with anticipation for what's coming next, make sure you visit our blogs frequently for news and announcements.

If you're already using Telerik UI for Blazor (or just about to use it) please share any and all feedback in our public feedback portal. As an early adopter of Telerik UI for Blazor your voice can be used to shape the future direction of the product!

For more insight into all things Blazor (not only related to our UI components) watch our very own Developer Advocate, Ed Charbeneau each week Friday at 12 EST on Twitch.

Join the Early Preview

We're excited to be part of the next generation of ASP.NET applications by supporting Blazor. Telerik UI for Blazor Early Preview is available for free today. The package currently includes Data Grid, Tab Strip, Button, NumericTextBox, and Window components written from the ground up to take full advantage of Blazor without JavaScript dependencies (there's no jQuery this time folks). This means Telerik UI for Blazor is native to Blazor. Throughout the year Microsoft will be working on Blazor (aka Razor Components) as part of ASP.NET Core 3.0. We plan on keeping Telerik UI for Blazor up to date as the project progresses and look forward to hearing your feedback, seeing what you've built, and learning what components you need for your next app.

Getting Started with the Popup Control for Xamarin.Forms

$
0
0

Popups are widely used in mobile applications to display alerts and notifications that provide the user with specific information, or to receive input. To make your life as a developer easier - our primary goal - I am happy to introduce to you the latest addition to the Telerik UI For Xamarin suite: the Popup control.

In short, the Popup control lets you display content of your choice on top of an existing view. The control includes a few useful configuration options, such as modality, to help you accomplish the scenario per the design you have. This blog post will walk you through the key features of Telerik UI for Xamarin Popup control.

Modal or Not Modal?

When you have a modal popup basically the user cannot interact with the UI behind it.  You can decide whether to define your popup as modal by setting the IsModal property.

In addition, RadPopup provides a way to set an overlay background color regardless of whether it is set as modal or not. Still, I assume this option will be more useful in the case of a modal popup to indicate the content behind is inactive.

Below, check out a quick sample of a modal popup with overlay background applied through the OutsideBackgroundColor property:

<telerikPrimitives:RadPopupx:Name="popup"
                    IsModal="True"
                    OutsideBackgroundColor="#6F000000">
    <telerikPrimitives:RadBorderCornerRadius="8"BackgroundColor="White"WidthRequest="300">
        <StackLayoutMargin="20">
            <LabelText="Latest Stories in Your Inbox"FontAttributes="Bold"FontSize="18"HorizontalOptions="Center"/>
            <LabelText="Sign up to be the first to get our expert written articles and tutorials!"TextColor="#4A4E52"FontSize="14"/>
            <telerikInput:RadEntry  WatermarkText="Enter your email address"  Margin="0, 10"BorderStyle="{StaticResource EntryBorderStyle}"/>
            <telerikInput:RadButtonMargin="10,20,10,20"BackgroundColor="#009EDB"TextColor="White"Text="Subscribe Now"Clicked="SubmitClicked"/>
        </StackLayout>
    </telerikPrimitives:RadBorder>
</telerikPrimitives:RadPopup>

Where Should You Position the Popup Control?

RadPopup provides a few useful properties which will help you position it per your preferences. Those include:

  • PlacementTarget property defines an element relative to which the popup is positioned when it is open; if you define RadPopup in XAML, it should be attached to an element which will be treated as placement target.
  • Placement property specifies the way the popup aligns to its placement target. Placement can be set to any of the Top, Right, Left, Bottom, Center or Relative options.
  • Furthermore, you could apply HorizontalOffset and VerticalOffset to set the horizontal/vertical distance respectively between the placement target and the alignment point.

I will take the modal popup defined above and will position it at the center of the screen by directly attaching it to the Page element and setting its Placement to Center:

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PopupTest"
            ...
             x:Class="PopupTest.MainPage">
    <telerikPrimitives:RadPopup.Popup>
        <telerikPrimitives:RadPopupx:Name="popup"
                            IsModal="True"
                            OutsideBackgroundColor="#6F000000"
                            Placement="Center">
        ...
        </telerikPrimitives:RadPopup>
    </telerikPrimitives:RadPopup.Popup>
    ...
</ContentPage>

Check how the above defined popup control looks when opened on iOS simulator:

Modal RadPopup

How Can You Configure the Animation?

RadPopup has a default animation applied of type Fade. You could switch it to Zoom type or disable the animation completely to make the popup show as quickly as possible.

Still, if you prefer setting an animation, you could also customize the duration and easing (acceleration over time) through AnimationDuration (in ms) and AnimationEasing (of type Xamarin.Forms.Easing) properties.

I have changed my Popup animation settings as shown below:

<telerikPrimitives:RadPopup.Popup>
    <telerikPrimitives:RadPopupx:Name="popup"
                        AnimationType="Zoom"
                        AnimationDuration="500"
                        IsModal="True"
                        OutsideBackgroundColor="#6F000000"
                        Placement="Center">
      ...
    </telerikPrimitives:RadPopup>
</telerikPrimitives:RadPopup.Popup>

You can see below how the popup is now displayed:

popup_gif

Learn More and Share Your Feedback

I hope I have managed to give you an overview on the basic features of the Popup control in Telerik UI for Xamarin, and feel free to check out the documentation if you're curious for more. We’re preparing a series of blog posts where we’ll take a look at more advanced scenarios with the control, so stay tuned.

In the meantime, we would love to hear your feedback about the Popup control and how we can improve it. If you have any ideas for features to add, do not hesitate to share this information with us on our Telerik UI for Xamarin Feedback portal.

If you have not yet tried the Telerik UI for Xamarin suite, take it out for a spin with a 30-day free trial, offering all the functionalities and controls at your disposal at zero cost.

How to Test Live Services with Fiddler AutoResponder

$
0
0

It’s always a challenge to test app features that go outside the scope of your local environment. In this post I’m going to talk about how we test our product automatic updates that use AWS (Amazon Web Services).

Simply put, our app will send a request to AWS and check if there is a new version of the product. If there is one, a specific behavior will activate locally, and an event will trigger on the local machine. What I as a QA engineer would like to test if these events trigger correctly.

Here lies the challenge though. It is not so easy for me to simulate the real life scenario - I’ll need to create a test environment for this service, an engineer will need to create a new build flavor of the product that is set to make requests to this new test environment, I’ll need to communicate with the Admin team in order to get permissions for our AWS account, and maybe few other things that will come up in the whole process. Or… I can avoid all that setup and make things a lot simpler and easier by using Fiddler instead.

Fiddler is a free tool and one of its powerful features is the ability to capture specific requests and return custom tailored responses to the client issuing the requests. Basically, it can act as man in the middle and this is very useful for testing. The AutoResponder can mock external services and help with testing specific behaviors triggered by responses from external providers.

It’s also useful if you are in the development phase where your feature is ready for test, but the web service is still not Live. Are you going to wait for the devops guys to setup everything or you will use Fiddler to create a mock response and complete most of your testing?

morpheus

I’ll show you an example of a real-life scenario and how I use the AutoResponder feature in my own testing. I’ll explain where the AutoResponder is in Fiddler, how to set it up and some of its useful options.

The AutoResponder tab is here:

1

You can manually add a request to match or import a set of recorded requests from a Fiddler archive. For the sake of the example I’m going to create a new rule. Setting up the rule is very simple. You just need to insert the request you need to intercept - in my case it is a request to AWS like this <https://telerik-teststudio.s3.amazonaws.com/TestStudioVersionManifest>:

2

The next step is to select what kind of response you want to get when Fiddler matches and intercepts this request. Here is where it gets interesting, as there is a lot of freedom in terms of what you can do depending on the situation. Editing the response, you can set specific errors like 202, 403, 502, etc. This is especially useful for negative test scenarios.

In my case I need this request to return a specific manifest JSON which tells the desktop app if there is a new version available for download. This is us testing a “check for update” feature after all:

3

It’s important to check “unmatched requests pass through,” as this will allow your normal requests to pass unobstructed through the Fiddler proxy:

4

This is mandatory for this example only. There are scenarios where you will probably need to stop all other requests from your machine and allow only the ones set in the AutoResponder.

Another interesting and useful option is to simulate Latency for the response request. This allows you to test how your app handles unexpected latency problems. Does it timeout gracefully? Does it recover as expected? Who knows? You will know if you test any outbound requests with the simulated Latency:

5

Easy Testing of Live Services with the Fiddler AutoResponder

In conclusion, the AutoResponder feature in Telerik Fiddler is very useful in cases where you need to mock a service, and then get a specific response during development by reaching an endpoint which is not ready for deployment on the Test/Live environments. It is also useful in negative testing scenarios or any tests where you need to simulate certain network conditions like slow network, random network errors and such.

If you have any feedback or comments, let us know in the comments below.

All About the Telerik WPF DataGrid

$
0
0

In this article we will take a deep dive into the Telerik WPF DataGrid and its key features, as well as how to load data into the component, optimize for performance, and style and customize it for a more modern and personal look and feel.

Line__Blue 2.3

Ever heard of DataGrids, GridViews or simply Grids? Well, if you are an application developer, the chances you have are quite high, as they can be found in just about any application that provides data management to its users - and for good reason.

Telerik UI for WPF - DataGrid Gif

If you are new to the topic, a DataGrid is an application control that displays data in a customizable - you guessed it - grid. Data grids provide you with a powerful and flexible way to display data to your application’s users in a tabular format, where the data can be either read-only or editable by the user depending on the use case.

Data displayed in a table with rows and columns is both easy to manipulate and represent, thanks to a variety of features, such as filtering, sorting and grouping. In this “big data”-driven world we live in today, people often work with huge data sets on a daily basis, across manufacturing, finance, banking, healthcare, retail, automotive and other industries. Data needs to be available, manageable and actionable throughout the organization and data grids are the key ingredient for making that happen. 

Due to the mass adoption of data grids (think of Microsoft Excel), people are so used to working with Excel-like spreadsheets that they intuitively expect to find the same set of functionalities in anything that even slightly resembles one - be it the airport terminal kiosk, the sales dashboards at work, the internal asset management software, medical records or email clients. 

Telerik UI for WPF - GridView - Pillar Page - Example Sales

As a consequence of the growing demand, the responsibility to replicate that experience in every single scenario falls on the shoulders of the developer. However, there is a lot to be done to meet the ever growing functionality needs of the user amid frequently changing design paradigms. Developers are left to figure out the best way to proceed. 

Anyone who has created an application data grid from scratch can back me up in saying that it can turn out to be a daunting task. This is especially true when trying to provide all the conventional functionalities (grouping, sorting, paging, filtering), while maintaining a great user experience. Trust me - I’ve been there and that’s precisely why I wanted to take the time and dig deeper into the most commonly requested and most frequently used data grid features, and how we’ve tackled them in our Telerik UI for WPF suite.

There are a variety of articles across the web that can help you create a conventional Microsoft default WPF Grid, most of which you've probably already read. So I want to take a different angle here and share insights from my perspective as both a creator and customer of the Telerik WPF DataGrid.

Line__Blue 2.3

Table of Contents:

(easily navigate to a specific section by clicking on it)

  1. DataGrids and the Developer Challenge
  2. Telerik WPF DataGrid Key Features
  3. Loading the Telerik WPF DataGrid with Data
  4. DataGrid Performance Tips and Tricks
  5. How to Style and Customize Your WPF DataGrid

Line__Blue 2.3

1. DataGrids and the Developer Challenge

DataGrid

Let’s consider the following scenario, as a basis for the topic: You are tasked with building a desktop application for the finance or healthcare industry. Together with your team, you’ve worked for countless hours and created the perfect architecture for your WPF app. You are using DI, MVVM, IoC and are getting the data from a web service, from the cloud or from a database (local or remote), and process it all in a testable and maintainable way. That’s what developers are good at and have done many times. Okay, I agree, that’s more than single scenario, but in any case, you do end up in the same situation:  

You must now present that data to the user in a easy to manage way, while also providing a great UI and user experience. This can be challenging and even the best can struggle. In the end, the end users of your application honestly don’t care what architecture you have used, as long as the app can get the job done. So if you are in a similar situation, and don’t want to spend countless hours in development, you might consider checking out the Telerik UI for WPF suite. This suite will be used as the basis of the topics in the following sections and the provided practical examples.

Below is an example of an Outlook-inspired application, which utilizes a few of the most commonly used controls and functionalities in WPF projects.

Telerik UI for WPF - DataGrid - Pillar Page - Mail example

In the sections to follow, we will cover the versatility and features of the toolkit, as well as some of the most commonly used and requested grid functionalities. These include populating and loading data into the grid, improving its performance and, last but not least, how to style and customize it and provide the application’s end users with an outstanding UX. In addition, you can check out the GitHub repository I will be referring to throughout the post.

Line__Blue 2.3

2. Telerik WPF DataGrid Key Features

WPF DataGrid Key Features Image

The Telerik WPF DataGrid is a powerful and easy-to-use component for desktop applications, which offers a variety of built-in features to cover a the vast majority of scenarios for line-of-business apps. 

We're going to cover a lot of ground in this post - feel free to read from the top or to skim to the feature that captures your interest.

Creating Columns

For the basis of a WPF datagrid we need rows and columns. Rows are obvious - they represent the objects in your data source. Columns on the other hand represent the properties of those objects. Most datagrids support automatic column generation. This feature allows you to show your data with minimal to no configuration. It is great for simple scenarios, or for situations in which the shape of data that will be presented is determined at runtime. Controlling the generated columns can be done using either the familiar Display attribute or the DataGrid AutoGeneratingColumn event. The latter gives you complete control over the generated columns and the generation process itself.

If you need more control over what and how columns get presented, you can define them manually. With the Telerik WPF DataGrid solution you have several different kinds of columns at your disposal: data, expression, checkbox, combobox, image, masked input, hyperlink. You can do quite a lot using those. And if you need something more, you can always define your own cell template. You have control over the column header and footer as well, so you can put things like images in the column header or add some text to the column footer. One feature that is very useful is column aggregates. With that feature you can add aggregate functions like min, max, sum, avg to the contents of your column and display the results in the column footer.

WPF DataGrid Columns Image

Grouping Your Data

Grouping your data is a very powerful and useful feature. Making it easy and user-friendly is one of the key features of the Telerik WPF DataGrid. Your users can easily group the data by simply dragging the desired column to the group panel. Multiple grouping is supported as well.

WPF DataGrid Grouping Image

Remember column aggregates? Well, when the data gets grouped, the aggregate functions work as well, giving you aggregate information about each group. This is built-in behavior and all you need to do to enable it is add aggregate functions to your columns and group your data.

WPF DataGrid Grouping Aggregates Image

One more thing. Because of the complexity, grouping a large data set on more than one level can lead to some performance issues. The Telerik DataGrid is prepared for such cases and employs a special kind of rendering. It is called flat group rendering mode and it is controlled by the GroupRenderMode property. It simply renders rows one below the other instead of nesting them on many levels.

Let’s Not Forget Sorting

This is pretty intuitive for any scenario. Customers are used to clicking on the column header and expect to find the familiar sort direction arrow, and they take it for granted that every datagrid should do it, whether for web, desktop or mobile. Of course, Telerik grids support column sorting and it works in the usual way. But there is more.

When your data is grouped you can change the sort direction of each group individually, and in addition, you can sort the data in each group by another column. This is indicated by the arrows shown in the group buttons appearing in the group panel and in the column headers, as can be seen in the screenshots I have added above. Sorting by more than one column is supported as well, so you can get that much more insight into your data.

The All-Mighty Filtering

One of my favorite built-in features is the column filtering (even though, I must admit, I am a bit biased ). The user can filter the presented data by their own criteria, which is especially useful in large and complex data sets. By default, all data bound columns have filtering enabled on them. You can opt-out of this behavior by disabling it if you feel that filtering on this column is not necessary. The filter window itself closely resembles what can be found in pretty much any spreadsheet processing tool.

WPF DataGrid Filtering Image

The filter for a given column picks up all the distinct values that are present in your data set for that particular column. The user can filter by simply selecting a specific value or values using the checkboxes. Advanced filter expressions are also supported. You can do filter expressions that check if the values in your columns start with a specific string value, or is greater, equal, lesser than or between given values. The possibilities are endless here and it is all done automatically for you and out of the box. The consumer of your data, when it is presented in a Telerik DataGrid, has all the filtering power they need.

Paging for Larger Datasets

Sometimes you just have too much data for the user to grasp at once. One popular solution is to use paging. Telerik UI for WPF has you covered with a special component made specifically for this purpose - the RadDataPager. It works in close cooperation with the DataGrid and it is a breeze to setup and configure.

WPF DataGrid Paging Image

Controlling the appearance and paging options starts with the DisplayMode property. It is of type PagerDisplayModes flag enumeration, and its members control what is displayed by the pager. You can also control the size of the page, which is the number of items displayed at once on the screen.

One nice thing about separating the component that does the paging from the DataGrid is that you can use the data pager with other components, like ListView, ComboBox or even charts. This can be helpful when building a dashboard, for example.

Row Details

When you have a lot of information and you can’t display it all using just columns, maybe you can show that information in a row detail. Each WPF DataGrid row is capable of presenting additional information if the form of a row detail. The advantage of this approach is that it can be configured to be displayed only when the row gets selected. This can reduce the number of columns and give your data grid a neater and more compact layout, while still providing all the information the user needs. You can also show the row details at all times, regardless of whether the row is selected or not, if you prefer.

WPF DataGrid Row Details Image

Configuring the row detail is done through the row details template. You have complete freedom with regard to what you put in there. You can display text, put in charts or even other DataGrids. The possibilities are endless.

Exporting to Various Formats

One of the benefits of using the Telerik UI for WPF toolkit is that you are stepping on the shoulders of giants. There is already an excellent document processing library that has been developed for Telerik tools, and of course it is well integrated into the Telerik WPF DataGrid. The data that is presented by the grid can be exported to many different formats for different applications, including Microsoft Excel (both xlsx and xls format are supported), and exporting to PDF and HTML is also possible. It all comes straight out of the box. You can customize it too.

One other way of exporting data is using the clipboard. The DataGrid supports both copying and pasting data from and to the clipboard and is very flexible in doing so. You have the option to copy the cells with or without the headers, footers, empty rows and columns.

Hierarchical Grid

Sometimes your data can be hierarchical with a parent - child relationship. Extending our current sample data, we can display the employees our managers are managing. The DataGrid can display such data using a nested DataGrid.

WPF DataGrid Nested Image

Note that the nested grid is a full blown DataGrid. The hierarchical support for the DataGrid handles self-referencing data sets as well. So, if your data has a ParentID relationship for example, your data is good to go. If not all of your data is forming a hierarchy you can hide or show the row expander icons by binding it directly to your data.

This feature can be useful in situations in which your data is truly hierarchical in nature and drilling down makes sense. This can also reduce the cluttering and data overflow in large data sets. When combined with lazy loading it can lead to performance improvements as well, because you will be fetching only the data you are actually showing on the screen.

Managing Data

Displaying data is great, but the Telerik DataGrid also allows you to modify the data it is presenting. You can perform insert, update and delete operations with validation and everything. In order to enable it you need to flip a few switches and you are good to go. Make sure to be sure your collection is not read-only and that the type of objects in your data set have a public default constructor.

WPF DataGrid Editing Image

This feature can be useful in some scenarios when your data set is not too complex. Another use case can be when you want to allow the user to edit values of particular cells without the hustle of opening up other views and filling up lengthy forms.

Theming

Last but definitely not least, your data is just a bunch of numbers without a beautiful and modern looking UI. There are plenty of readily available themes you can apply to the DataGrid and any Telerik component for that matter. Two of my favorite themes are the Material and Fluent themes. In the screenshots above you can see the Windows 8 theme, another great one.

Material Theme

GridViewTheme1

Fluent Theme

GridViewTheme2

Applying a theme to your DataGrid is a breeze. Just reference the theme that you desire and merge its resources in your App.xaml file. Why the merge? Because Telerik NoXaml assemblies, which are the recommended ones, have no Xaml files inside of them. In order to give your WPF DataGrid the right appearance, you have to reference a theme and merge the resources in your application. This separation allows for the packing of theme dependent resources in different assemblies and reduces the overall size of dependencies and your application, because you are only referencing what you actually need.

Another benefit of the NoXaml assemblies is that you can customize the built-in themes very easily. You can change absolutely anything, starting from a color to completely retemplating the whole component. When you just need to give a specific component some style you will be pleased to know that there are many different APIs for doing that. Keep reading to learn more.

Line__Blue 2.3

3. Loading the Telerik WPF DataGrid with Data

WPF DataGrid Loading Data Image

Data. It comes in all shapes and sizes and it's in the core of all applications. Of all the types of visualizations, the data grid is the most widely used and ubiquitous.

Today, we are going to discuss how to load your Telerik GridView with different flavors of data in an MVVM-friendly way. Why? Because MVVM allows us to separate the code that prepares the data for display and is responsible for handling user input from the code that manages the view. Also, MVVM is purposely built for WPF.

If you are new to MVVM or need a refresher, take a moment to read an introduction to the MVVM pattern. In this post, I will assume you have a basic understanding of how MVVM works. If you don't need MVVM and just want to visualize your data in a code-behind, don’t worry—you will still find some nuggets of wisdom here. 

Basic Data Binding

Let's start with the basics. Data grids display data in rows and columns and in order to display your data, you need a collection of objects. For each item in your collection, a new row is added to the grid. The columns are constructed from the public properties of your objects. You can either use automatic column mapping or take manual control and define the columns yourself. In either case, there is no good or bad way, but an automatic and a manual one.

WPF PivotGrid image 

On many occasions people consider using a grid when in fact they need a pivot. If your data is more like measures and dimensions with multiple layers of nesting, rows and column totals like in the image above, then take a look at the RadPivot. It is a purpose-built component for displaying data in a pivot that enables users to add or remove measures and dimensions on the fly.

Let's see how we can databind our grid. (Check out the official documentation here.)
We start by defining a model—I’ll use a simple Employee model. Next, we need a view model with a public property that will expose our collection of employees. Let's first start with simple in-memory data.

publicclassMainViewModel : ViewModelBase
{
    privateObservableCollection<Employee> _data;
 
    publicObservableCollection<Employee> Data
    {
        get=> _data;
        set
        {
            if(_data == value)
                return;
 
            _data = value;
            this.RaisePropertyChanged();
        }
    }
}

Let’s use this model and bind the ItemsSource property of the RadGridView. It is of type IEnumerable, as you would expect, and indeed it can accept any enumerable. This behavior is very similar to what we have in the standard WPF toolbox. However, the grid checks the inbound collection and there are some special types that influence the grid behavior. This is where the Telerik DataGrid has some hidden treasures.

One special collection is the ObservableCollection, which implements the INotifyCollectionChange. Like other WPF components, changing the contents of that collection in your view model will inform the DataGrid of the change and it will update accordingly. New rows will be added or old ones removed—nice!

Grouping, Sorting, Filtering

There is another special collection that ships the Telerik assemblies and this is the QueryableCollectionView or QCV. It ends in view because it intends to serve as a facade over your collection. It allows you to manipulate your data from your ViewModel trough the QCV API. In order to use it, you wrap your data inside of it and pass it to the GridView. For example, if you want to filter the data, you can do it in the following way:

publicMainViewModel()
{
    _data = newObservableCollection<Employee>(SampleData.Employees);
    _dataView = newQueryableCollectionView(_data); // Wrap data in a collection view
}
 
publicQueryableCollectionView Data => _dataView;
 
privatevoidOnFilterData(objectobj)
{
    var descriptor = newFilterDescriptor(nameof(Employee.LastName), FilterOperator.StartsWith, "P");
    _dataView.FilterDescriptors.Add(descriptor);
}

Sorting is similar, just tap the SortDescriptors property. You can group in a similar way—adding GroupDescriptors will group your grid. The DataGrid understands the QCV and will update its UI to indicate the data manipulation. Notice the plural in the descriptors property. You can add multiple descriptors to do multiple groups, sorts and filters. One more thing—if you have multiple data operations on the QCV, then you can defer its refresh to speed it up like this:

privatevoidOnSortData(objectobj)
{
    var descriptor = newSortDescriptor() { Member = nameof(Employee.LastName), SortDirection = ListSortDirection.Descending };
    _dataView.SortDescriptors.Add(descriptor);
}

As a testimonial to the DataGrid understanding of the QueryableCollectionView, when the user applies grouping in the UI, the collection of group descriptors gets updated. You can observe the changes to this collection and perform some logic when the user groups the grid. This can be tremendously useful on many occasions when you need to be informed about a user performing an action on the data. You can obviously subscribe to the events of the GridView, but this is not very convenient for MVVM. That's the exact reason why Microsoft has created a number of special interfaces like the ICollectionView, which we saw today in the form of QueryableCollectionView.

Dynamic Data

In most cases, you already know the schema of the data prior to the application launch. But sometimes this information is obtained only after the app starts. An example I can give you straight away is CSV file visualization. The schema of the CSV file can change from file to file and it is known after the user selects the file. In cases like that, the plain old System.Data.DataTable and DataView can be your friend. Just create a DataTable, populate it with the rows and columns of the CSV file and data bind to the grid view. The Telerik DataGrid understands this classical type and will display its structure as you expect.

privatevoidRefreshData(objectobj)
{
    this.Data = this.GenerateRandomData();
}
 
staticDataView GetSampleView()
{
    DataTable table = newDataTable();
    table.Columns.Add("Weight", typeof(int));
    table.Columns.Add("Name", typeof(string));
    table.Rows.Add(57, "Koko", "Shar Pei", DateTime.Now);
    table.Rows.Add(130, "Fido", "Bullmastiff", DateTime.Now);
     
    returntable.DefaultView;
}

A word of warning here. As cool as the DataTable API is, you should restrain yourself from using it except for cases of dynamic data as described above or when you are migrating an existing code base to WPF. Querying databases and displaying their data can be done using other, more modern techniques. There are number of good reasons for this.

Getting Data from a Database

Long gone are the days that you have to write your SQL statements in code with string concatenation and commands. ADO.NET is still here with us and there may be some situations in which you can rely on old faithful, but ORM frameworks like EntityFramework have rescued us from writing boring boilerplate code. Using an ORM framework has many advantages, including:

  • Saving a lot of time
  • Minimizing boilerplate code
  • Executing data operations on the server blazingly fast using IQueryable
  • The ability to replace one database server with another with minimal effort
  • Database versioning and automatic migrations
  • Automatically creating database from your models

There are many ORM frameworks out there and WPF developers are spoiled with choice. Microsoft offers EntityFramework and the open-source version, called EntityFrameworkCore. EntityFrameworkCore is getting a lot of attention lately and it is becoming more mature with each subsequent version. In WPF, it has one distinct advantage over EF and this is built-in support for client-side SQLite databases. Having a small-in-size, fast relational database source can be tremendously useful for any WPF app. For example, I have used SQLite to store indexing information of some huge local directories. This way, the search experience can be improved significantly because your file search can be reduced to a simple search in a relational table. Other examples include the caching of remote data for faster application startup and retrieval.

Check out Gina's blog post for a step-by step tutorial on how to add EF core to your WPF project. You can find one demo project in the series GitHub repository. It uses EF Core in a WPF application with migrations, SQLite and everything, and it displays the data in a DataGrid.
 

Line__Blue 2.3

4. DataGrid Performance Tips and Tricks

WPF DataGrid Performance Image

Good performance is vital for a good application user experience, which makes it a key priority for all applications. As you know, users hate slow and laggy applications and that's why performance is one of the highest concerns for developers and managers alike.

The Telerik WPF DataGrid is optimized for dealing with huge datasets, however, there are some things that should be kept in mind when dealing with large data sets. Fortunately, there are lots of tweaks that you can apply to the WPF DataGrid in order to get top performance, which traditionally fall into one of two categories: reducing the UI complexity or reducing the amount of data being processed.

Reducing UI Complexity

Application performance begins to slow down when there is too much going on in the UI thread.In WPF applications one of the reasons could be the complexity and size of the visual tree. Simply put, when there are lots of visual objects that need to be measured, arranged and painted, the time needed for those operations can increase beyond what is considered reasonable.

The DataGrid is a complex control with lots of features and because of that, the number of UI elements created on the screen is huge. That's a common problem among many WPF components, as the more complex the UI component, the more UI elements get created. If we examine the visual tree created for a simple GridView with 10 rows and 5 columns, you will find that it has spawned 1,339 visual elements (using the Windows 8 theme). It must be noted here that the Telerik DataGrid utilizes advanced techniques like UI element virtualization, so it only creates as many visual elements as can be displayed on your screen. But still, the complexity of these elements is the problem.

The creators of the Telerik WPF DataGrid have recognized this problem and have provided an intuitive solution: light templates that significantly reduce the number of UI components created. In order to use them, you have to use no-XAML binaries and you also have to opt-in.

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
       <ResourceDictionarySource="/Telerik.Windows.Themes.Windows8;component/Themes/System.Windows.xaml"/>
       <ResourceDictionarySource="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.xaml"/>
       <ResourceDictionarySource="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.Input.xaml"/>
       <ResourceDictionarySource="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.GridView.xaml"/>
    </ResourceDictionary.MergedDictionaries>
   
    <StyleTargetType="telerik:GridViewRow"BasedOn="{StaticResource GridViewRowCoreValidationStyle}"/>
    <StyleTargetType="telerik:GridViewCell"BasedOn="{StaticResource GridViewCellCoreValidationStyle}"/>
</ResourceDictionary>

The code snippet above is everything needed to opt-in for the lightweight templates, but for it to work, you must use the no-XAML binaries and implicit themes, as already mentioned.

You may ask “why did I have to opt-in for something that improves performance? Why isn’t it enabled out of the box?” Well, here's the gist - these templates disable some of the DataGrid features like row details and hierarchical grid. Basic effects like hover and selection as well as grouping are still enabled, so make sure you check your grid before enabling those light templates.

So far, we haven't talked numbers, so let's do that. Let’s enable the light templates in our simple 10-by-5 grid and check the number of visual elements spawned. Now the number is 919, a 31% reduction. That means faster loading, scrolling and performance overall. There is a good in-depth analysis in this blog post dedicated to light templates with more numbers and statistics. Be sure to check it out.

Another neat trick to reduce UI complexity is to use fixed width for your columns. Configuring all of your columns to use a specific size will help your GridView in measuring and arranging your columns, which in turn will increase both horizontal and vertical scrolling performance.

Reducing the Amount of Data

DataGrids are components that are data-centric. Because of their nature, they are usually filled with a lot of data. It is not uncommon to see a grid with tens of thousands of rows because grids are so easy to read and understand.

But loading a collection with millions of objects requires a lot of memory. Data operations on those objects can also be slow if not done properly. You can, of course, implement some partial loading as well as fast sorting and filtering that operate on huge datasets, but there is an easier way. There are some techniques you can utilize to reduce the number of objects loaded in memory at once and utilize the underlying database or remote service more efficiently.

Enter IQueryable. IQueryable, compared to IEnumerable (which is the contract used by most ItemsControls in WPF), allows some data-savvy components to not only get the items needed for display, but also create queries that can potentially be executed on a remote computer. Take, for example, sorting. If you have a million rows of data and you want to sort them, this can be time consuming if not done properly. However, a database can sort a dataset much faster if an index exists on the subject column.

Paging or filtering are other data manipulations that can see a huge boost if executed on the server. Not only that, but when you want to filter, sort and then read the data only a few records at a time, then the task at hand becomes very difficult if you don't use IQueryable. When using IQueryable, you can request only a single page from your data source at a time—and I am not talking about paging an in-memory data using some UI, but actually loading only a bunch of objects into memory from the underlying datasource. This can be much more efficient in terms of memory and transport.

Imagine loading 1 million rows from a remote service, then parsing them from JSON to POCO, only to display 20 objects. That's hugely inefficient. IQueryable allows you to request only the objects that you need from the comfort of dotNet. What the Telerik WPF grid offers is a special descendant of QueryableCollectionView that utilizes the power of IQueryable on your behalf—meet the VirtualQueryableCollectionView. If you want to obtain the items from your database 20 rows at a time, you can expose your data as IQueryable and wrap it in a VirtualQueryableCollectionView with LoadSize set to 20. Then, just pass this virtual collection to the Data Grid and voila—the GridView will now create queries for obtaining the data.

publicclassMainViewModel : ViewModelBase
{
    publicMainViewModel(IEmployeeService employeeService)
    {
        IQueryable query = _employeeService.GetEmployees();
        this.Employees = newTelerik.Windows.Data.VirtualQueryableCollectionView(query) { LoadSize = 20 };
    }
 
    publicTelerik.Windows.Data.VirtualQueryableCollectionView Employees { get; }
}

Just this simple code change is all that is required to start using the power of IQueryable in your code. You will immediately notice the faster loading of your grid. Sorting and filtering will also be done using queries, written for you by the DataGrid engine, and will execute much faster. Not only that, distinct column values, used by the filtering window, will be acquired faster. This means that the window itself will display faster. So, all in all, the DataGrid will display faster and be more responsive.

The Mighty VirtualGrid

Sometimes all you need is to display your data in just rows and columns and you don't need the advanced features of the DataGrid. Telerik engineers have created a component from the ground up for speed and performance and it is called the Virtual Grid (a.k.a. RadVirtualGrid). In the gif below, you can see an example of scrolling through more than a trillion cells (yes, that's a trillion!)

Telerik UI for WPF - Virtual Grid - Scrolling a trillion cells gif

It lacks some of the more advanced features that DataGrid has like hierarchical grids, but it makes up for those missing features with speed. If you are serious about performance and responsiveness, and you want to display thousands and millions of rows of data, then you should definitely consider using this component. We talked about UI complexity and I have shown you some numbers for the DataGrid using light and regular templates. Well, the number of UI elements spawned to display the Virtual Grid is... 55. That's right, 55!

Feature

DataGrid

VirtualGrid

Scrolling


Filtering

Grouping

Sorting

Selection

Alternation

Paging

Row and column resizing

Managing data (add, edit, delete rows)

Mouse support

Keyboard support

Limited

Touch support

Limited

Merged cells

Pinned rows

Custom columns

Hierarchical grid

Row details

Knowing when to use Virtual Grid or regular DataGrid is the name of the game. From my experience, the Virtual Grid is more than enough feature-wise so you can usually swap your DataGrid with Virtual Grids safely. 

If some of the missing features are a must, you can combine the two components together. You can display the entire dataset using virtual grids and when the user wants to view a particular portion of the data in more detail, you can display this data in a DataGrid. Utilizing the QueryableCollectionView we talked about above is very neat in scenarios like this, because it gets populated with the proper FilterDescriptors whenever your users apply filters to your virtual grid. You can use this as an opportunity to populate your DataGrids and perhaps some graphs to create a dashboard. Users love that.

Line__Blue 2.3

5. How to Style and Customize Your WPF DataGrid

WPF DataGrid Theming Image

The Telerik WPF DataGrid is highly customizable component
. Long gone are the days when the theme we got from the distributor was set in stone and couldn't be modified. With the power and flexibility of WPF, you can customize every part of the Telerik DataGrid—and any component for that matter.

One of the coolest WPF features is the styling and template mechanism. Styles allow you to set the properties of a component in a tidy way and create a configuration that can be shared among many instances. Templates allow you to take control over the appearance of a component using ControlTemplate or the appearance of data using DataTemplate. What the creators of the DataGrid have done is take advantage of this mechanism and allowed you, the developer, to modify the appearance of the GridView (and any component for that matter) very granularly. 

All Telerik components have their styling and appearance declared as implicit styles and bundled together as themes. Out of the box, the Telerik DataGrid comes with a bunch of themes defined in separate assemblies. There are dark and light themes, a Material and touch-friendly theme. There are themes influenced by Microsoft Office. The list gets updated constantly with new releases.

The good thing about this vast array of themes is that you can find at least one that suits your needs. And even better, updating the appearance can be done in several ways as I am going to show you today. So, if you want to change the background of a row, you have several approaches that you can follow. The Telerik team has identified the most common styling needs and handled them gracefully so that you don't need to re-template anything unless you really need to.

DataGrid exposes a number of properties that can be used to easily customize it without the need to modify its template. You can show or hide specific DataGrid components, like the group panel that sits at the top, the column headers and footers, the row indicator and many more. Being WPF, you can either set these properties directly on the DataGrid as in this code snippet:

<telerik:RadGridViewShowGroupPanel="False"GridLinesVisibility="Vertical"
                     ShowColumnHeaders="False"ColumnBackground="Bisque"
                     RowIndicatorVisibility="Collapsed"/>

Alternatively, you can also define them in a style. Your style can either be implicit as in this code snippet or be a regular style with a key. Just remember to inherit from the theme style. Why is that? Well, remember that the Telerik team has defined everything style-related in the theme assemblies. Every component has two sets of styles for it: a named style, named like: <componenet_name> Style. So, in our code snippet we need to inherit from RadGridViewStyle. That gives us the control template and all other settings. Now you can use your style anywhere in our app. Easy, right?

<Grid>
    <Grid.Resources>
        <StyleTargetType="{x:Type telerik:RadGridView}"BasedOn="{StaticResource RadGridViewStyle}">
            <SetterProperty="ShowGroupPanel"Value="False"/>
            <SetterProperty="GridLinesVisibility"Value="Vertical"/>
            <SetterProperty="ShowColumnHeaders"Value="False"/>
            <SetterProperty="ColumnBackground"Value="Bisque"/>
            <SetterProperty="RowIndicatorVisibility"Value="Collapsed"/>
        </Style>
    </Grid.Resources>
    <telerik:RadGridView/>
</Grid>

And here is how that will affect the grid styling:

WPF DataGrid - Styling Image

There are a bunch of properties for you to tweak, which fall into several categories. First, you have properties that show or hide grid components:

  • ShowColumnFooters
  • ShowColumnHeaders
  • ShowColumnSortIndexes
  • ShowGroupFooters
  • ShowGroupPanel
  • ShowScrollPositionIndicator
  • ShowSearchPanel
  • GridLinesVisibility
  • RowIndicatorVisibility
  • RowDetailsVisibilityMode

You can use those to remove a grid component that you don't need like we have done in the code snippet above. Then you have a group of properties that can control the size of the rows and columns: 

  • ColumnWidth
  • MaxColumnWidth
  • MinColumnWidth
  • RowHeight
  • VisibleRowsHeight

In the last group are properties, which define styles, style selectors and templates for various grid components:

  • RowStyle & RowStyleSelector
  • AlternateRowStyle & AlternateRowStyleSelector
  • GroupFooterRowStyle & GroupFooterRowStyleSelector
  • GroupHeaderTemplate
  • GroupPanelItemStyle & GroupPanelStyle
  • GroupRowStyle & GroupRowStyleSelector
  • HeaderRowStyle
  • NewRowStyle
  • RowDetailsStyle & RowDetailsStyleSelector
  • RowDetailsTemplate & RowDetailsTemplateSelector
  • MergedCellsStyle & MergedCellsStyleSelector
  • HierarchyChildTemplate & HierarchyChildTemplateSelector

Some of these properties have corresponding components that can be styled using implicit style. Take, for example, a row. You can style all rows using a single style, either set to the RowStyle property or an implicit style that targets GridViewRow. Both of those approaches will work and can be shared among all your data grid instances, so choose the one that suits you. You can also use style selectors to apply some custom logic depending on your concrete objects and choose a specific style for specific rows.

<Grid>
    <Grid.Resources>
        <Stylex:Key="MyGridRowStyle"TargetType="{x:Type telerik:GridViewRow}"BasedOn="{StaticResource GridViewRowStyle}">
            <Style.Triggers>
                <TriggerProperty="IsSelected"Value="True">
                    <SetterProperty="Foreground"Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <StyleTargetType="{x:Type telerik:GridViewRow}"BasedOn="{StaticResource MyGridRowStyle}">
            <SetterProperty="Background"Value="SeaGreen"/>
        </Style>
        <StyleTargetType="{x:Type telerik:GridViewHeaderRow}"BasedOn="{StaticResource GridViewHeaderRowStyle}">
            <SetterProperty="Background"Value="MidnightBlue"/>
        </Style>
    </Grid.Resources>
    <telerik:RadGridViewItemsSource="{x:Static local:SampleData.Employees}"AlternationCount="2">
        <telerik:RadGridView.AlternateRowStyle>
            <StyleTargetType="{x:Type telerik:GridViewRow}"BasedOn="{StaticResource MyGridRowStyle}">
                <SetterProperty="Background"Value="LightGoldenrodYellow"/>
            </Style>
        </telerik:RadGridView.AlternateRowStyle>
    </telerik:RadGridView>
</Grid>

Resulting in the following: 

Styling Rows in Telerik WPF DataGrid

But wait a minute! Where are the style properties for cells? You have two options: Either style all cells in your grid at once using an implicit style that targets GridViewCell or style columns individually. To do that, you need to define your columns manually and then you have access to the properties that control the cell appearance. The GridView data column have properties for:

  • CellStyle
  • CellStyleSelector
  • CellTemplate
  • CellTemplateSelector
  • CellEditTemplate
  • CellEditTemplateSelector
  • FooterCellStyle
  • HeaderCellStyle
  • GroupHeaderTemplate
  • GroupHeaderTemplateSelector 

As you can see, you can easily control every aspect of your cells in a very granular fashion without the need to redefine the complete cell template. And because this is WPF, you have style and template selectors, which you can use to apply some custom logic when selecting a template or a style for your cells. Also, you can use triggers and data triggers in your styles for runtime precision customization.

<Grid>
    <Grid.Resources>
        <StyleTargetType="{x:Type telerik:GridViewCell}"BasedOn="{StaticResource GridViewCellStyle}">
            <SetterProperty="Background"Value="#ffcc00"/>
        </Style>
        <StyleTargetType="{x:Type telerik:GridViewHeaderCell}"BasedOn="{StaticResource GridViewHeaderCellStyle}">
            <SetterProperty="Background"Value="LimeGreen"/>
            <SetterProperty="Foreground"Value="Cyan"/>
        </Style>
    </Grid.Resources>
    <telerik:RadGridViewItemsSource="{x:Static local:SampleData.Employees}"AutoGenerateColumns="False">
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumnHeader="Name"DataMemberBinding="{Binding FullName}"/>
            <telerik:GridViewDataColumnHeader="Department"DataMemberBinding="{Binding Department}"/>
            <telerik:GridViewDataColumnHeader="Salary"DataMemberBinding="{Binding Salary}"DataFormatString="{}{0:C0}">
                <telerik:GridViewDataColumn.CellStyle>
                    <StyleTargetType="{x:Type telerik:GridViewCell}"BasedOn="{StaticResource GridViewCellStyle}">
                        <SetterProperty="Background"Value="Green"/>
                        <Style.Triggers>
                            <TriggerProperty="IsSelected"Value="True">
                                <SetterProperty="Background"Value="Red"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </telerik:GridViewDataColumn.CellStyle>
            </telerik:GridViewDataColumn>
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
</Grid>

The outcome is the following: (yes, it's not a very practical example and it's a bit of an eye-sore, but you get the idea :) )

Styling Cells in Telerik WPF DataGrid

This is just the tip of the iceberg. DataGrid is composed of dozens of components that can be styled individually the same way we have styled rows and columns in the snippets above. Together with the style and template selectors, triggers and templates, you can take the visualization of your data in your hands. 


Line__Blue 2.3

Summary

Well that's all folks! I hope you found this article helpful to get yourself better acquainted with the DataGrid control in the Telerik UI for WPF suite. We went in-depth through all of the key features of the control, as well as how to bind data to the grid, theme, style and customize it, and last, but definitely not least got to explore a few performance optimization tips and tricks.

One thing is for sure - DataGrids are widely popular and are often an integral part of a project's requirements for most line-of-business apps. Should you find yourself in need of one, consider the Telerik WPF DataGrid, as you will be able to save months of development time by getting the fully-featured control straight into your app. For what's it's worth, I have personally tested it extensively and used it to create quite a few client applications myself and can assure you that it is a very powerful and versatile component for visualizing data in a table-like fashion. Unarguably, It is a great tool for displaying your data and making decisions based on it.

If you decide to give it a try for yourself, go ahead and tap on the link below, where you can get a free 30 day trial of the complete Telerik UI for WPF suite, which also includes over 130 additional controls and a variety of themes.  

Download Telerik UI for WPF Free Trial

In case you are still up for some additional reading, here are two extra blogs on the WPF DataGrid:


Chasing Success with Xamarin Apps

$
0
0
We're starting up a series of articles exploring the modern Xamarin ecosystem and essential tools for making successful mobile apps.

Mobile is hard. Developers have been building for mobile form factors for years now - yet mobile strategy and choice of technology stack continues to be heavily debated. While there are justifications to build specifically for chosen mobile platforms, developers are increasingly choosing to build cross-platform mobile apps from a single code base. Thankfully, irrespective of the technology stack, developer tooling is fairly mature now. Top-notch SDKs, choice of IDEs, deployment options and access to native APIs should help most developers choose to build for mobile the way they want to.

Mobile apps also do not live in silos. The desired continuity of user experience is best served by cloud infrastructure - public, private or hybrid. No matter what be the technology choice, it is easy to augment mobile apps with features that only the cloud can provide. The mobile app landscape is also fiercely competitive and developers will want to do everything possible to keep their users engaged. This often means making mobile apps more intelligent and plain fun to use. So the bottom line is - mobile developers need a ton of ammunition to be successful. 

Cross-platform mobile development has largely been democratized for .NET developers – thanks to Xamarin. If choosing the Xamarin technology stack, you're coming into a rich developer ecosystem with polished tools and services. However, professional Xamarin development isn't a piece of cake - there is a lot one has to do to be successful. Let's do a run down of the most common tools, services and techniques that Xamarin developers should be using to fall into the pit of success.

This post is a placeholder for a series of articles over several weeks aimed at understanding the Xamarin ecosystem better and knowing the essentials that make your app awesome. The list below will light up with links as content is published... here goes:

  1. Why Xamarin - Mobile Strategies | Understand the .NET Ecosystem 
  2. Xamarin Platform Reach - Mobile | Desktop | UWP | Wearables | Web
  3. Essential Tools - IDEs | Developer Utilities | MVVM Frameworks | Polished UI 
  4. App Building Blocks - NuGet | Components | Xamarin Essentials
  5. App Templates - Visual Studio | MVVM | Common Screens | Bundled UI
  6. Deployment Tools - Previewer | Simulators | Live Player | Devices
  7. Platform Hotness - Xamarin.Forms 3.x | Xamarin.Forms 4.0
  8. Cloud Data - Azure | Kinvey | AWS 
  9. Cloud BaaS - Authentication | Push Notifications | Offline sync | Elasticity
  10. Serverless - Mobile specific workflows | Azure Functions | Amazon Lambdas
  11. App Intelligence - Cognitive Services | Vision | QnA Maker | NLP/Luis
  12. App Conversations - ChatBots | Bot Framework | Azure Bot Service | Integrations
  13. Network Utilities - Fiddler | Postman | Reflector
  14. DevOps - VS App Center | Test Cloud | App Analytics
With the modern Xamarin technology stack, your code goes places and developers have all the ammunition to light up engaging app features. Let’s recap the ecosystem, understand tools, glimpse into the future and equip ourselves to build amazing mobile apps. 

Cheers to success!

First Look: Forms and Validation in Razor Components

$
0
0

Let's look at the new forms and validation feature just added to Razor Components. We'll start with an overview of the forms and validation implementation, then look at what is included out of the box. We'll finish with an example of how to use it all.

It's been another great release for Blazor/Razor Components fans. We've had some cool new additions including pre-rendering and improved event handling, but I think the big one is forms and validation.

In this post, I'm going to give you a first look at this new feature. We'll start with an overview of how everything works, then take a look at the new components we have available to us, and finished up by looking at an example of their usage.

Overview of Forms and Validation

Many of you may be glad to hear, that, out of the box, validation is based on data annotation, similar to MVC. This is a great starting point, as it's already such a well-established pattern in ASP.NET (MVC, Razor Pages).

Again, for anyone who's had experience with forms and validation in ASP.NET previously, there are a couple of familiar components. There's a validation summary component and a validation message component, which work in the same way as their namesakes in MVC.

But what if you're not a fan of data annotations? Well, that's ok too. As has been the case with Blazor since the start, the team has been very good at giving developers options where they can. Forms and validation are no different.

Although out of the box data annotations are included, you are free to swap them out for another validation system of your choice and fluent validations perhaps? If you don't like the default behavior of the new input controls, you can create your own. You can pretty much tailor the forms and validation system to your liking.

What's in the Box?

Let's have a quick look over the new components that are included with forms and validation. As I said before, if you have any experience with ASP.NET MVC applications, then some of the names are probably going to look familiar to you.

EditForm

This is your starting point when creating a form. This component wraps all form controls, it provides the infrastructure for managing form validation, and it provides some useful events to hook into when submitting the form: OnValidSubmit, OnInvalidSubmit and OnSubmit.

You can use OnValidSubmit and OnInvalidSubmit together, but OnSubmit can only be used alone. When using OnValidSubmit the framework will trigger validation for you, but when using OnSubmit you are responsible for making sure the form is valid.

The other important parameter to know about is the Model parameter. This is the top level model object for the form. It's in this object where you would specify your data annotations that the form will use for validation.

DataAnnotationsValidator

The DataAnnotationsValidator component enables data annotations support for the form. If you wanted to use a different method for validation, then you could swap this component out and replace it with another implementation.

ValidationSummary

This component will list out the validation errors in your form as a simple list. You would usually place this at the top of your form. Again, this will sound very familiar if you've had previous experience with data annotations validation.

ValidationMessage

Very similar to the ValidationSummary component, the ValidationMessage component differs by showing the validation errors for a specific input field, specified using the For parameter. You would usually place this component close to the field it's validating.

Input Components

There are now six new components covering various input types. These are designed to work seamlessly with the components above to handle validation.

  • InputText
  • InputTextArea
  • InputNumber
  • InputCheckbox
  • InputSelect
  • InputDate

The names are pretty self-explanatory, but it's worth pointing out that InputData and InputNumber have some basic value parsing so an invalid date or a non-number value will automatically show as a validation error, which is neat. You may have also noticed that there is no radio button component out of the box. If you need to validate radio buttons, for now, you will need to write your own.

Usage Example

Now that we know what the building blocks are, let's have a look at how we can use them. We'll set up a simple form using the following model.

public class Film
{
  [Required, StringLength(50, ErrorMessage = "Title must be 50 characters or less")]
  public string Title { get; set; }

  [Required]
  public DateTime ReleaseDate { get; set; }

  [Range(1, 5, ErrorMessage = "Rating must be from 1 to 5")]
  public int Rating { get; set; }

  [Required]
  public string Genre { get; set; }

  public bool IsWatched { get; set; }

  [StringLength(500, ErrorMessage ="Comments must be 500 characters or less")]
  public string Comments { get; set; }
}

I'm going to add the code for the form and then we can break it down to make sure it all makes sense.

<EditForm Model="@film" OnValidSubmit="@HandleFormSubmit">
  <DataAnnotationsValidator />
  <ValidationSummary />
  <div>
    <label for="title">Title: </label>
    <InputText Id="title" bind-Value="@film.Title" />
  </div>
  <div>
    <label for="release-date">Release Date: </label>
    <InputDate Id="release-date" bind-Value="@film.ReleaseDate" />
  </div>
  <div>
    <label for="rating">Rating</label>
    <InputNumber Id="rating" bind-Value="@film.Rating" />
  </div>
  <div>
    <label for="genre">Genre</label>
    <InputSelect bind-Value="@film.Genre">
      <option value="horror">Horror</option>
      <option value="thriller">Thriller</option>
      <option value="comedy">Comedy</option>
      <option value="action">Action</option>
      <option value="romance">Romance</option>
    </InputSelect>
  </div>
  <div>
    <label for="watched">Watched</label>
    <InputCheckbox Id="watched" bind-Value="@film.IsWatched" />
  </div>
  <div>
    <label for="comments">Comments</label>
    <InputTextArea Id="comments" bind-Value="@film.Comments" />
  </div>
  <button type="submit">Submit</button>
</EditForm>

@functions {
  Film film = new Film();
  
  void HandleFormSubmit()
  {
    Console.WriteLine("Form is valid! Send the data.");
  }
}

To start with, we're using the EditForm component to define the form. The Model parameter is set to the film instance declared in the functions block, and the HandleFormSubmit method is registered to the OnValidSubmit event.

Next is the DataAnnotationsValidator. This tells the form that we want to use data annotations to validate our fields. Then we have a ValidationSummary component, which will display any validation errors our form has.

The rest of the form is declaring the various input controls for the properties on our film object. Notice that they use the bind-Value syntax. If you've not seen this before, it is two-way binding. There are other options for binding values that offer greater control, but they are out of the scope of this post.

If we run the above code, it will look something like this:

Forms and Validation Example

Summary

In this post we had a first look at the new forms and validation feature in Razor Components. We did an overview of how forms and validation works, looked at what's included out of the box, as well as covered a simple usage example.

For More on Building Apps with Blazor

Want to learn about creating great user interfaces with Blazor? Check out Telerik UI for Blazor. It's currently in public preview, so give it a try and please let us know what you think. You can learn about the latest release (at time of writing that's 0.3) here.

WPF MultiColumnComboBox, GridView Column ComboBox and More

$
0
0

In this post, we'll cover some of the latest additions to the Telerik UI for WPF suite in R1 2019: the official MultiColumnComboBox, new DataGrid column and SpreadProcessing integration. Let's dive in.

The DataGrid (a.k.a. RadGridView) is one of the major controls in the Telerik UI for WPF suite, and we've been continuously adding new features and improvements to it based on users' request and industry/market trends. As our main goal is for you to create top-of-the-line applications, we focus our efforts on delivering exceptional experience with our products. Depending on the assignment, RadGridView can combine its powers with other controls to win your heart. Keep reading to find out more!

But first, let's talk about the...

Official MultiColumnComboBox

As of R1 2019, we introduced the official version of MultiColumnComboBox, which allows RadGridView to show multi-column data in the dropdown of a ComboBox-like control. The beta version offered quite a lot of functionality, but we added some new features based on clients’ requests. I will list the most thrilling of them here:

  • You can now choose between SelectionBoxes and text-based selection interface by setting the SelectionBoxesVisibility property. Customize your SelectionBoxes by using the SelectionBoxTemplate, SelectionBoxStyle, SelectionBoxTemplateSelection and SelectionBoxStyleSelector properties.
  • Add a custom footer to MultiColumnComboBox by either using FooterContent property, or by defining your own Footer template.
  • CodedUI Level 2 and 3 support is also included in the new release.
  • You prefer a read-only MultiColumnComboBox? Closing the dropdown after selection is the desired behavior for your clients? And you want to customize the GridView placed in the drop down? Check all these features in the latest official version.

GridViewMultiColumnComboBoxColumn in Our Data Grid

Our radars detected that you want a GridViewMultiColumnComboBoxColumn. Roger that!

You no longer need to customize GridViewComboBox column to have the desired multiple columns in the combobox. The new built-in column is represented by a standard TextBlock in view mode similarly to most of the other columns in RadGridView. In edit mode, its component is our shiny MultiColumnComboBox. Shape the edit element by setting the rich set of properties, have a tabular data in the drop down and configure your column similarly to any other column that derives from GridViewBoundColumnBase.

One thing that hasn’t been feasible till now is to have a multi-value GridView cell. Just pass it a collection property and set SelectionMode to multiple – MultiColumnComboBox’s selected items get synchronized with the given collection. Easy as that.
<telerik:RadGridViewItemsSource="{Binding Clubs}"AutoGenerateColumns="False">
            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumnDataMemberBinding="{Binding Name}"/>
                <telerik:GridViewMultiColumnComboBoxColumnHeader="Players"ItemsSourceBinding="{Binding Players}"DataMemberBinding="{Binding SelectedPlayers}"DisplayMemberPath="Name"SelectionMode="Multiple"Width="*"/>
                <telerik:GridViewDataColumnHeader="Established"DataMemberBinding="{Binding Established}"ShowColumnWhenGrouped="False"/>
                <telerik:GridViewDataColumnHeader="Std.Capacity"DataMemberBinding="{Binding StadiumCapacity}"/>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>

And here is the result of the above code snippet:

Selecting multiple items in GridViewMultiColumnComboBoxColumn
Selecting multiple items in GridViewMultiColumnComboBoxColumn

RadGridView Export Integrating RadSpreadStreamProcessing

Have you used RadSpreadStreamProcessing, part of Telerik Document Processing suite? It is a document processing paradigm that allows you to generate XLSX and CSV files with minimal memory consumption and excellent performance.

A nice enhancement in RadGridView is the integration with RadSpreadStreamProcessing, resulting in a faster synchronous and asynchronous export. Its great advantage - writing the GridView content directly to a stream without loading the entire document in the memory - leads to a two times faster export time compared to a RadSpreadProcessing integrated export.

Asynchronously exporting 10000 rowsAsynchronously exporting 10000 rows

Check the documentation for more details on GridViewSpreadStreamExport.

Feedback and Improvements

It is important for us to hear what you think about our new controls and improvements, so we can understand how we can do better in the future to meet and exceed your expectations. Please share your thoughts in our Feedback portal or in the comments section below.

Don't forget to check what else is available in Telerik UI for WPF with R1 2019 and to download a trial today.

 Start my WPF Trial

Why Xamarin

$
0
0

While there are many ways to build for mobile form factors, let's explore what's in it for developers if they choose the Xamarin technology stack.

Even after years of building for mobile, developers still heavily debate the choice of technology stack. Perhaps there isn't a silver bullet and mobile strategy really depends - on app, developer expertise, code base maintenance and a variety of other factors. If developers want to write .NET however, Xamarin has essentially democratized cross-platform mobile development with polished tools and service integrations. Why are we then second guessing ourselves?

Turns out, mobile development does not happen in silos and all mobile-facing technology platforms have evolved a lot. It always makes sense to look around at what other development is happening around your app - does the chosen stack lend itself to code sharing? Are the tools of the trade welcoming to developers irrespective of their OS platform? Do the underlying pillars of chosen technology inspire confidence?

Let's take a deeper look and justify the Xamarin technology stack. Spoiler - you won't be disappointed.

This article is a part of a long content series on Chasing Success with Xamarin Apps - we explore the Xamarin technology stack, tools and services that help developers build successful mobile apps.

Mobile Strategies

While there are variety of ways to build for mobile, the following are the broad categories:

MobileStrategy

Thankfully, whichever technology stack mobile developers choose, there's mature tooling and easy access to mobile platform APIs. Let's discuss some pros and cons of each approach however:

  • Native: The most straightforward way of building for mobile is native apps for iOS, Android and Windows. Native apps run closest to the metal and developers get to use platform-specific SDKs/languages/tools. While fast and beautiful, native apps are rather expensive, requiring maintenance of platform-specific code bases.

  • Mobile Web/PWAs: The lowest hanging fruit to go cross-platform with mobile is often mobile web - there are plenty of frameworks that help web applications work nicely on mobile browsers. Mobile web apps can be taken to extreme smartness through Progressive Web Apps - where web apps start behaving as legitimate citizens in the mobile app world. Users can pin web apps to their home screens, have service workers run in the background and get push notifications. There is a lot of tooling help when building mobile web and mature JavaScript SPA frameworks for building PWAs.

  • Hybrid: Cordova popularized the idea of building cross-platform mobile apps with web technologies - HTML, CSS and JS bundled together to make a mobile app. Such hybrid apps ran within the browser shell and the user would not notice if done well. While hybrid apps enjoy good tooling, mature frameworks like Ionic and app store presence, the browser sandbox does hamper their runtime speed a little.

  • JS Native: The last few years have been witness to the rise of cross-platform mobile apps written in JavaScript/Typescript - the point is, why go hybrid when you can go native with the same technologies? JS Native apps enjoy complete native platform access and render native UI - all from a single code base. JS Native apps enjoy wonderful frameworks like NativeScript, NativeScript with Angular/Vue integration, React Native and Flutter.

  • X-Compiled: If you would rather write .NET code and use familiar tooling like Visual Studio, the cross-compiled mobile app solution is rather enticing. The trick is compiling higher level .NET language code into binary bits for each mobile platform, all the while rendering native UI. Xamarin has largely democratized the X-compiled space, with the Uno platform lending a helping hand of late.

While you'll find this article advocating for the Xamarin technology stack, the point of this mobile strategy discussion is that you don't have to always do Xamarin to reach cross-platform mobile. If you are invested in the web stack and happy writing JS/TS, the web route of getting to mobile form factors will yield rich dividends and lend itself better to code sharing.

All the .NETs

As one dives into the Xamarin technology stack, it is often beneficial to taka a step back and understand the .NET ecosystem - where does Xamarin fit? Here's the big picture story with .NET:

DotNets

As developers know, the .NET stack has evolved a lot in the past couple of years. There are multiple .NETs for different types of apps - to be read as multiple Base Class Libraries (BCLs). The three most popular ones are:

  • .NET Framework: This is the full .NET Framework that has the been the darling of developers on the Microsoft stack for 17 years now. The .NET Framework provides as rich an ecosystem as you can get - top notch tools, community support, extensibility and runtime for hosting variety of .NET applications. Over the years however, the .NET Framework has shown obvious bloat and the monolithic nature of the framework invites brittleness, as well as upgrade headaches. Make no mistake, the .NET Framework isn't dying and remains a core part of Windows. However, it may not see serious innovations going forward - existing apps would continue to run fine, but any greenfield development should look ahead at other .NETs.

  • .NET Core: This is the new .NET, built from ground up to address some of the concerns of .NET Framework. .NET Core is lean, modular and for the first time, boasts a cross-platform runtime taking .NET apps to MacOS/Linux. While new, .NET Core has seen rapid innovations and sports near-par API features compared to the .NET Framework. The lightweight nature of .NET Core lends itself naturally for building high performance web applications, while the command line/cross-platform tooling provides developers with liberties. The benefits of side-by-side .NET runtimes are stretching back to desktop with .NET Core 3, while .NET Core itself pushes the envelope with technologies like ML.NET.

  • Mono: Since the inception of .NET, there has been a desire to take .NET apps outside of Windows. Meet Mono - the port of .NET APIs to other platforms that is as old as the .NET Framework itself. Mono is the runtime for all Xamarin applications and remains an incredibly versatile way of supporting .NET on an increasing number of non-Windows platforms.

It is not hard to see how this variety of .NETs in the ecosystem provides flexibility - developers get to choose which .NET works best for their apps. Xamarin running on Mono is a very important piece of the puzzle for Microsoft - it is what gives .NET the extensive platform reach. With all the .NETs, there are very few devices/platforms that modern .NET developers cannot reach.

Mono or .NET Core

Mono has always been a great natural fit as a runtime for Xamarin apps. Developers write .NET code which is compiled down to generic Intermediate Language (IL) code, and then the Mono bridge/virtual machine translates .NET IL to native assembly code for iOS/Android or other platforms. It is only recently that much of .NET became open source - prior to that, Mono painstakingly made .NET code portable and executable on other platforms.

However, there is .NET Core now, which is modern, versatile and cross-platform. Developers in the Xamarin ecosystem have wondered of late - could .NET Core actually replace Mono as the runtime for Xamarin apps?

MonoNetCore

While it is enticing to expect everything out of the new polished runtime, the realities dictate otherwise. Turns out, age does make you wise and Mono, to this day, sports a bigger API surface area than .NET Core. Mono is also very performant for .NET apps running on iOS/Android - both through IL interpretation or statically compiled. Mono is also way ahead of the game in .NET implementations on future-facing platforms, like the all-important WebAssembly. So, it is safe to say that Mono is here to stay and power .NET apps across a wide variety of platforms.

The other question to consider is fragmentation of .NET. While having various .NET BCLs optimized for different platforms is nice, is the present state of the ecosystem inviting confusion for developers? Does it make sense for Microsoft or the open source community to maintain so many .NET? Perhaps a unification of the various runtimes is called for - only time will tell.

How to Xamarin

Developers choosing the Xamarin technology stack to build for mobile can be assured of a solid performant runtime and a plethora of rich tooling. This frees up developers from having to worry about the logistics of building an app, and lets them just focus on the app itself. As one gets started with Xamarin, there are two broad choices:

Xamarin iOS/Android

From the early days of Xamarin, the goal was to write .NET code that could be shared across mobile platforms, and this is traditionally what is called Xamarin.iOS/Android. Often dubbed Xamarin Native, the goal is to have a shared code layer written in .NET and platform-specific projects for the UI part of the mobile apps.

XamarinNative

The goal with Xamarin.iOS/Android is to abstract out as much of the app feature set as possible into a .NET code library - this is shared across all platforms. While a great step in the right direction, Xamarin Native does require developers to build the UI layer of each supported mobile platform on its own. This means developers do need to know how to build app UI for iOS, Android and Windows natively - all pulled together into a single project and referencing the shared library.

So when should developers choose to build with Xamarin iOS/Android? Xamarin Native is a good choice in general when mobile apps tend to cater heavily to a certain platform - where lots of native behaviors and custom UI are called for. Mobile games are also served well with Xamarin Native - essentially, Xamarin.iOS/Android is a good choice anywhere developers want to run as close to the metal as they can. Xamarin Native still benefits from a shared .NET code layer, but the UI is written natively for each mobile platform. Additionally, Xamarin.Forms (see below) can now be embedded inside of Xamarin Native, thus getting the best of both worlds.

Xamarin.Forms

What started out as a prototyping tool for cross-platform abstractions has grown into what we call Xamarin.Forms today. In addition to the shared .NET code, there is a layer of shared UI that stretches across platforms and renders corresponding native UI. This shared UI layer is an abstraction allowing developers to write .NET code/markup, which gets translated to native UI on each platform at/before runtime. Xamarin.Forms has the huge benefit of .NET developers not having to know the intricacies of building iOS/Android UI by hand.

XamarinForms

Keep in mind though, Xamarin.Forms is trying to solve an incredibly hard problem - a consistent UI abstraction layer that renders native UI on platforms that are uniquely different. While Xamarin.Forms has a large breadth of control coverage, the developer community and partner ecosystems fill in the gaps with cross-platform UI. If developers are up for it and app demands it, developers can always jump down to native UI land from Xamarin.Forms by writing custom renderers for platform-specific behaviors or rendering native UI controls on a per platform basis.

So Why Xamarin Again?

The bottom line is, it is 2019 and hopefully mobile isn't an afterthought. A legitimate mobile strategy reduces developer frustration and allows for code reusability. If you are invested in web technologies, modern mobile web, hybrid or JS native apps are the way to go - you have rich tooling and plethora of native API access.

If however you want to go with the .NET option, Xamarin is an easy choice. Here are some indicators that will help you make up your mind that you want to choose the Xamarin technology stack:

  1. You want to write C#/F# code
  2. You are comfortable with XAML as a markup language
  3. You care for maximum code reusability with other .NET projects
  4. You want to stay within the comforts of Visual Studio
  5. You expect a solid runtime, polished tools and a rich ecosystem

Convinced about Xamarin? Your code is in good hands and the future looks awesome.

Choose Time Intervals with the TimeSpanPicker for WinForms

$
0
0

No more using multiple date time pickers to setup your time intervals. We are happy to introduce the brand new TimeSpanPicker control for WinForms applications. Learn all about the new control in the following article.

We've received multiple requests through the WinForms feedback portal to add a time span picker to the Telerik UI for WinForms suite and they have not been disregarded. In case you missed it, as of earlier this year, with the Telerik R1 2019 release, the new TimeSpanPicker control is available in the suite.

The RadTimeSpanPicker is a UI component that provides full control over selecting a specific time span and duration within certain ranges using the built-in components for days, hours, minutes, seconds and milliseconds.

Meet RadTimeSpanPicker

Imagine that we need to implement a flight booking system. First, we need to place a couple of DropDownLists for the from/to destinations, a DateTimePicker for picking the date of the flight and perhaps a filter for how long flight we will need. Here, in the last part, is where the RadTimeSpanPicker comes into play.

time-span-picker-flight

What we did above to configure the control is simply place it in the form and set its Format, and then we get the value the user entered from the Value property. We can also use the ValueChanged event to get notified when the Value property is changed. As simple as this.

this.radTimeSpanPicker1.Format = "'Under 'hh' hours'";
 
privatevoidRadTimeSpanPicker1_ValueChanged(objectsender, EventArgs e)
{
    TimeSpan flightDuration = this.radTimeSpanPicker1.Value.Value;     
    // filter the flights
}

Other Useful Functionalities of the Control:

  • Negative values – useful to show time overdue cases
  • Binding – through the simple data binding
  • Localization – make the control speak any language with the convenient localization provider
  • EditMode – various edit modes are provided to capture the different use cases the control can be used in
    • Mask – limit the user to just use the text box to modify the value
    • Popup – limit the user to pick only predefined values from the pop-up
    • Combined – give the user full flexibility
  • Step properties – define the steps for each component, e.g. by 10min, by 2 hours, etc.
  • ReadOnly – this lets you display time span information to the user without allowing editing, or allows you to enable/disable the editing capability per some business logic
  • Null Values support – the control happily accepts null as Value, which is useful in data bound scenarios, in this case the NullText property can be used to show prompt text
  • SpinButtons – a convenient feature that you can enable for users to change the value with the built in buttons in the text box
  • Various events are at your leisure to get informed of value being changed (ValueChanging and ValueChanged), pop-up open/close (PopupOpened/Closed), as well as convenient extensibility point where we can plug in custom logic (the ComponentCreated and ComponentsCreated events of PopupContentElement) - more on this topic later

Structure

The control consists of two main elements: RadMaskedEditBoxElement and RadTimeSpanPickerContentElement.

RadMaskedEditBoxElement

RadMaskedEditBoxElement allows users to modify the value directly in the text box and at the same time validates it. The Format property specifies which portions of a time span value can be edited. The default format is “dd:hh:mm:ss.fff”

time span picker

To add specific content to the format string you will need to enclose it with single quotes. Here is an example that shows this.

this.radTimeSpanPicker1.Format = "dd' days, 'hh' hours, 'mm' minutes, 'ss' seconds, 'fff' milliseconds'";

time span picker custom format

RadTimeSpanPickerContentElement 

RadTimeSpanPickerContentElement is the main element of the pop-up and hosts a collection of components. Each component represents a different part of the TimeSpan object.

time span picker popup

We provide five default time span part components, so you can easily set up the time intervals you wish to pick:

  • DayTimeSpanPickerComponent
  • HourTimeSpanPickerComponent
  • MinuteTimeSpanPickerComponent
  • SecondTimeSpanPickerComponent
  • MillisecondTimeSpanPickerComponent.

Components are created each time the value of TimeSpanPickerElement Format property is changed, based on the desired format (for example: if the format is “dd:hh”, day and hour components will be created when the pop-up is opened).

Custom Components

We’ve provided a way to handle scenarios which require a custom time span as well.

For example, if you want the user to be able to pick one week intervals, you can easily implement it by creating a custom BaseTimeSpanPickerComponent and overriding its GetValueInTicks() and SetValue(TimeSpan value) methods. GetValueInTicks returns a TimeSpan value as ticks corresponding to the selected item from the UI component. SetValue is used to set the value of the component and choose which part of the TimeSpan value we want to use.

publicoverridelongGetValueInTicks()
{
    doubleweeks = this.WeeksListTimeSpanPickerUIComponent.GetSelectedValue();
    returnTimeSpan.FromDays(weeks * 7).Ticks;
}
 
publicoverridevoidSetValue(TimeSpan value)
{
    doubleweeks = value.Days / 7d;
    this.WeeksListTimeSpanPickerUIComponent.SetSelectedValue(weeks);
}

The BaseTimeSpanPickerComponent has a UI part, which is used to display the values to the end users. By default, we use RadListElement to list all available values. Now let’s add specific text to the values displayed in the list. We will override the CreateItemsSource method, which is used to create our items based on three properties: Minimum, Maximum and Step. In this case, we customize the displayed text and align it to the right. Here is what our custom UI component looks like:

publicclassWeeksListTimeSpanPickerUIComponent : ListTimeSpanPickerUIComponent
{
    publicWeeksListTimeSpanPickerUIComponent(ITimeSpanPickerComponent owner) : base(owner)
    { }
 
    protectedoverridevoidCreateItemsSource()
    {
        base.CreateItemsSource();
        foreach(RadListDataItem item inthis.ListElement.Items)
        {
            item.Text = item.Value + " weeks";
            item.TextAlignment = ContentAlignment.MiddleRight;
        }
    }
 
    publicdoubleGetSelectedValue()
    {
        returnthis.GetValue();
    }
 
    publicvoidSetSelectedValue(doublevalue)
    {
        this.SetValue(value);
    }
}

To include our custom component, we need to override the CreateVisualElement method of our WeekTimeSpanPickerComponent. We will also define our Minimum, Maximum and Step values and set the header text. The whole class looks like this:

publicclassWeekTimeSpanPickerComponent : BaseTimeSpanPickerComponent
{
    publicWeekTimeSpanPickerComponent(ITimeSpanPickerContentElement owner) : base(owner)
    {
        this.Minimum = 0;
        this.Maximum = 10;
        this.Step = 0.5;
        this.UpdateLocalization();
    }
 
    publicoverrideBaseTimeSpanPickerUIComponent CreateVisualElement()
    {
        returnnewWeeksListTimeSpanPickerUIComponent(this);
    }
 
    publicWeeksListTimeSpanPickerUIComponent WeeksListTimeSpanPickerUIComponent
    {
        get{ returnthis.TimeSpanPickerUIComponent asWeeksListTimeSpanPickerUIComponent; }
    }
 
    publicoverridelongGetValueInTicks()
    {
        doubleweeks = this.WeeksListTimeSpanPickerUIComponent.GetSelectedValue();
        returnTimeSpan.FromDays(weeks * 7).Ticks;
    }
 
    publicoverridevoidSetValue(TimeSpan value)
    {
        doubleweeks = value.Days / 7d;
        this.WeeksListTimeSpanPickerUIComponent.SetSelectedValue(weeks);
    }
 
    publicoverridevoidUpdateLocalization()
    {
        this.TimeSpanPickerUIComponent.HeaderText = "Select Weeks";
    }
}

The last step is to tell our RadTimeSpanPicker to use this newly created component. To achieve this, we need to subscribe to the ComponentsCreated event of PopupContentElement, where we will remove all default generated components and insert our custom one.

this.radTimeSpanPicker1.PopupContentElement.ComponentsCreated += this.PopupContentElement_ComponentsCreated;
 
privatevoidPopupContentElement_ComponentsCreated(objectsender, EventArgs e)
{
    ITimeSpanPickerContentElement contentElement = this.radTimeSpanPicker1.PopupContentElement;
    contentElement.Components.Clear();
    contentElement.Components.Add(newWeekTimeSpanPickerComponent(contentElement));
}

time span picker popup weeks

In the end, we will add just a few more lines of code to show how you can add a new button next to the Close button, which will be used to reset the value of RadTimeSpanPicker.

TimeSpanPickerDoneButtonElement buttonPanel = (radTimeSpanPicker1.PopupContentElement asRadTimeSpanPickerContentElement).FooterPanel;
 
RadButtonElement clearButton = newRadButtonElement("Clear");
clearButton.Click += ClearButton_Click;
buttonPanel.LayoutPanel.Children.Add(clearButton);

And a code sample that shows how to access the panel with buttons and clear the value of RadTimeSpanPicker:

privatevoidClearButton_Click(objectsender, EventArgs e)
{
    RadButtonElement button = (RadButtonElement)sender;
    TimeSpanPickerDoneButtonElement buttonPanel = button.FindAncestor<TimeSpanPickerDoneButtonElement>();
    buttonPanel.Owner.SetValueAndClose(null);
}

time span picker popup clear button

Try It Out and Share Your Feedback

For more details about RadTimeSpanPicker, you can visit the online documentation and take a look at the demos. For any further feature or control requests, make sure to log them into the WinForms Feedback portal.

If you in search for a comprehensive WinForms UI toolkit for your current or upcoming desktop project and have not yet had the chance to explore Telerik UI for WinForms, you can find detailed information on the product page. You can also download a free 30-day trial to explore it in-depth and evaluate whether it will be a right fit for your application.

Viewing all 1954 articles
Browse latest View live