Posts Tagged ‘c#

07
Apr
12

Streamsocket example c# metro

Peter Daukintis

This is a very basic example of socket communication in a c# metro-style application using StreamSocket and StreamSocketListener. It mirrors the Simple StreamSocket example in msdn here http://code.msdn.microsoft.com/windowsapps/StreamSocket-Sample-8c573931 which is coded in c++ and javascript but no c#. I decided to roughly convert it as a learning exercise – please note I haven’t tested the code in that many scenarios and haven’t handled failure cases and errors much.

A socket provides send and receive over TCP and a StreamSocketListener will listen for incoming TCP connections.

The sample will act as a server or client depending on which buttons you press, i.e. press listen to be a server and connect to be a client. Also, you can set the same program as client and server ad have it communicate with itself.

To start the listener wire up a connection received event handler and bind the service name…

_listener.ConnectionReceived += listenerConnectionReceived;
await _listener.BindServiceNameAsync("3011");

The event handler stores the incoming socket in a list (so it can use it to reply), and waits for incoming data from it. The ‘waiting for incoming data’ bit looks like this…

async private void WaitForData(StreamSocket socket)
{
    var dr = new DataReader(socket.InputStream);
    //dr.InputStreamOptions = InputStreamOptions.Partial;
    var stringHeader = await dr.LoadAsync(4);

    if (stringHeader == 0)
    {
        // disconnected
        return;
    }

    int strLength = dr.ReadInt32();
    uint numStrBytes = await dr.LoadAsync((uint)strLength);
    string msg = dr.ReadString(numStrBytes);
    WaitForData(socket);
}

It uses a DataReader to read from the incoming socket and then calls itself to wait for subsequent incoming message data.

Note that the samples use a protocol which sends the length (number of bytes) of the message first followed by the message data itself. If you want to use a different strategy, for example characters to delimit the start and end of a message then the code will change a little bit. The difference being that you won’t always know how much data to read. You can modify the code like this to accommodate this:

async private void WaitForData(StreamSocket socket)
        {
            var dr = new DataReader(socket.InputStream);
            dr.InputStreamOptions = InputStreamOptions.Partial;
            var stringHeader = await dr.LoadAsync(512);

            // change the rest acccordingly….

Note that setting the InputStreamOptions to Partial will allow you to specify a larger buffer but also the async load operation will complete when a smaller sized buffer comes in. This enables you to read the data coming in and respond to it accordingly.

The pictures show a session between a socket server running on a build slate and a win8 vm both on my local network..

socketexampleservertablet

socketexampleclientvm

The project can be downloaded from here.

https://skydrive.live.com/redir.aspx?cid=4f1b7368284539e5&resid=4F1B7368284539E5!445&parid=4F1B7368284539E5!123

UPDATE: This project has been updated for the Release Preview

http://sdrv.ms/Nema94

04
Apr
12

metro c#–simple transform using touch

Well, this turned out to be pretty easy Smile……

The aim was to carry out a simple image transform with touch; so pinch zoom, translate and rotate. This is how the code turned out.

First, the xaml, which is an Image inside a Canvas…

 

<Canvas>
    <Image x:Name="myImage"
           ManipulationMode="All"
           ManipulationDelta="Image_ManipulationDelta_1"
           RenderTransformOrigin="0.5, 0.5">
        <Image.RenderTransform>
            <CompositeTransform></CompositeTransform>
        </Image.RenderTransform>
    </Image>
</Canvas>

 

Then the event handler for the ManipulationDelta event

 

private void Image_ManipulationDelta_1(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var ct = (CompositeTransform)myImage.RenderTransform;
    ct.ScaleX *= e.Delta.Scale;
    ct.ScaleY *= e.Delta.Scale;
    ct.TranslateX += e.Delta.Translation.X;
    ct.TranslateY += e.Delta.Translation.Y;
    ct.Rotation += 180.0 / Math.PI * e.Delta.Rotation;

    UpdateControls(ct);
}

 

And here’s the sample running on my Build slate…

 

PinchZoomSpam

 

The code is available here…

https://skydrive.live.com/redir.aspx?cid=4f1b7368284539e5&resid=4F1B7368284539E5!443&parid=4F1B7368284539E5!123

25
Mar
12

metro c# webapi client

Peter Daukintis

For my own purposes I wanted to create a test application which I can use as a test-bed to experiment with user interface aspects of Metro. I decided to create a simple REST web service and make create/read/update/delete type calls to it from a c# metro application. Pretty much the next step up from ‘Hello World’ for a web connected application.

First, to create the Web API choose ASP.NET MVC 4 Application from the New Project Dialog and in the ensuing dialog select WebApi. We are using the ASP.NET MVC 4 Beta which now includes the WebApi (http://www.asp.net/web-api); which was formerly known as WCF WebApi.

The template creates a ValuesController to expose the sample CRUD methods (GetCollection/Get/Post/Put/Delete). It uses a string as the payload so I’m going to change that to use a Person class.

public class Person
{
    static int idGen = 123456;
    public Person()
    {
        Id = ++idGen;
    }
    public Person(Person other)
    {
        Id = other.Id;
        Name = other.Name;
        Occupation = other.Occupation;
    }

    public string Occupation { get; set; }
    public string Name { get; set; }
    public int Id { get; private set; }
}

Next, I renamed the ValuesController to PeopleController and modified the template code to query a list of Person objects:

public class PeopleController : ApiController
{
    private List<Person> _list = new List<Person>
        {
            new Person{ Name = "fred", Occupation = "plumber" },
            new Person{ Name = "bob", Occupation = "lawyer" },
            new Person{ Name = "flo", Occupation = "pilot" },
        };

    // GET /api/people
    public IEnumerable<Person> Get()
    {
        return _list;
    }

    // GET /api/people/5
    public Person Get(int id)
    {
        return _list.SingleOrDefault(p => p.Id == id);
    }

    // POST /api/people
    public void Post(Person value)
    {
        _list.Add(value);
    }

    // PUT /api/people/5
    public void Put(int id, Person value)
    {
        var item = _list.SingleOrDefault(p => p.Id == id);
        if (item != null)
        {
            item.Name = value.Name;
            item.Occupation = value.Occupation;
        }
    }

    // DELETE /api/people/5
    public void Delete(int id)
    {
        var item = _list.SingleOrDefault(p => p.Id == id);
        if (item != null)
        {
            _list.Remove(item);
        }
    }

I’m not worried about the correctness or completeness of the http responses and behavior here as this post is about the client side of the code. Making the above code changes is enough to expose my RESTful api. For this example I an running the server on IISExpress on localhost – this enables me to test the GET calls using the browser by typing in http://localhost:60442/api/people to IE10 on the Desktop. (since web api returns JSON by default I made the modification to the registry described here http://stackoverflow.com/questions/2483771/how-can-i-convince-ie-to-simply-display-application-json-rather-than-offer-to-do to easily view the data coming back).

 

WebApiResponse

(I tested the other HTTP verbs using Fiddler by constructing requests by hand).

With that done it’s over to the Metro client.

I started with a blank c# Metro Style application and added a GridView to which I would bind my ViewModel (I tend to use the MVVM pattern). To support my MVVM architecture I rolled up a few helper classes; a DelegateCommand and a ViewModelBase class to provide INotifyPropertyChanged and an IsDesignMode property. The Expression Blend designer doesn’t work with network calls so the IsDesignMode property is used to facilitate design time data.

Next, I created some design-time data to enable me to design the ui in Blend

if (IsDesignMode)
{
    People = new ObservableCollection<Person>
    {
        new Person { Name = "design fred", Occupation = "Nurse" },
        new Person { Name = "design bob", Occupation = "Artist" },
        new Person { Name = "design flo", Occupation = "Teacher" },
        new Person { Name = "design zak", Occupation = "Fireman" },
        new Person { Name = "design rita", Occupation = "Nurse" },
    };
}

Here’s how it looked in Blend:

DesignData

With this out of the way I could get to the heart of the problem – making the client-side calls:

Starting with retrieving the initial list

var http = new HttpClient();
var resp = await http.GetAsync(new Uri(apiRoot));
var stream = await resp.Content.ReadAsStreamAsync();
var djs = new DataContractJsonSerializer(typeof(List<Person>));
People = new ObservableCollection<Person>((IEnumerable<Person>)djs.ReadObject(stream));
stream.Dispose();

Then, Deleting a Person from the list

var http = new HttpClient();
var resp = await http.DeleteAsync(new Uri(apiRoot + "/" + Selected.Id));
resp.EnsureSuccessStatusCode();

Then, editing and adding, which I implemented in the same function:

var http = new HttpClient();
var djs = new DataContractJsonSerializer(typeof(Person));
var ms = new MemoryStream();
djs.WriteObject(ms, person);
ms.Position = 0;
var sc = new StreamContent(ms);
sc.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

var resp = original == null ?
        await http.PostAsync(new Uri(apiRoot), sc) :
        await http.PutAsync(new Uri(apiRoot + "/" + original.Id), sc);

ms.Dispose();
resp.EnsureSuccessStatusCode();

In order to invoke the CRUD commands I added an application bar and populated it with app bar command buttons which I data bound to ICommands exposed by the View Model.

 

appbar

 

One thing worth mentioning is that in order to edit the Person objects I needed some form of editor page. I wasn’t sure of the best Metro-Style way to implement it, but in the end I went for a modal dialog which looked similar to the built in message box.

 

PersonEditor

 

I created this as a full screen UserControl.

 

The solution containing the web api project and the metro c# client is here https://skydrive.live.com/redir.aspx?cid=4f1b7368284539e5&resid=4F1B7368284539E5!442&parid=4F1B7368284539E5!123.

UPDATE: An update for the Release Preview is here http://sdrv.ms/N4kfZT

17
Mar
12

metro background audio c# (consumer preview)

Peter Daukintis

Some changes occurred in the consumer preview release of Windows 8 regarding background audio; the steps required to get it working are outlined in this forum post

http://social.msdn.microsoft.com/Forums/en-AU/winappswithcsharp/thread/2d3496df-a145-4d87-be08-aadd5a8098e2

The steps are

  • Create a MediaElement and set it’s AudioCategory property to ‘BackgroundCapableMedia’
    <MediaElement x:Name="myMedia"
                  Source="/Assets/Sleep Away.mp3"
                  AudioCategory="BackgroundCapableMedia"/>

  • Update the app manifest to declare Background Tasks of types ‘Audio’ and ‘Control Channel’
  • Implement event handlers for
    • MediaControl.PlayPressed
    • MediaControl.PausePressed
    • MediaControl.PlayPauseTogglePressed
    • MediaControl.StopPressed

 

public BlankPage()
{
    this.InitializeComponent();
    MediaControl.PlayPressed += MediaControl_PlayPressed;
    MediaControl.PausePressed += MediaControl_PausePressed;
    MediaControl.PlayPauseTogglePressed += MediaControl_PlayPauseTogglePressed;
    MediaControl.StopPressed += MediaControl_StopPressed;
}

private void MediaControl_StopPressed(object sender, object e)
{
    myMedia.Stop();
}

private void MediaControl_PlayPauseTogglePressed(object sender, object e)
{
}

private void MediaControl_PausePressed(object sender, object e)
{
    myMedia.Pause();
}

private void MediaControl_PlayPressed(object sender, object e)
{
    myMedia.Play();
}

The media transport event handlers which need to be implemented are detailed here http://msdn.microsoft.com/en-us/library/windows/hardware/hh833781.aspx

 

Here’s a working sample project.

https://skydrive.live.com/redir.aspx?cid=4f1b7368284539e5&resid=4F1B7368284539E5!440&parid=4F1B7368284539E5!123‏

UPDATE: I have updated this for the Release Preview (see http://babaandthepigman.wordpress.com/2012/08/12/metro-background-audio-c-release-preview/)




Follow

Get every new post delivered to your Inbox.