Showing posts with label xaml. Show all posts
Showing posts with label xaml. Show all posts

Saturday, March 8, 2008

Bag-o-Tricks March '08 Edition

January 12 was my last update to the bag-o-tricks. I couldn’t let two months go by without another refresh. There is a lot of stuff here I've already talked about. The code has been available via SVN for a while, but not in the convenient package.

The Goods

Binaries and Source [zip, 4.17MB]. Tested with Visual C# Express 2008.

The Details

  • VS Copy-to-HTML - New!
    • Blogged about it here.
  • NotifyWorker - New!
    • Blogged about it here.
  • HueConverter - New!
    • Makes it easy to create a pretty spectrum of colors for a number of items
  • Animating Tile Panel
    • Renamed AnimateNewItem property to AnimatesNewItem
    • Made initial load not animate new items
    • Polished the demo code
  • CompositionTargetRenderingListener
    • Added Dispose and used it where appropriate
    • Added WireParentLoadedUnloaded helper method
  • DemoCollection
    • Added Reset command
    • Moved to library assembly
  • Extentions
  • FlipTile3D
    • Moved to WrapperElement<Viewport3D>
  • FolderPicker
    • Moved to new SelectRecursive implementation
  • WPFUtil
    • Added HSB-RGB converter
    • Created ‘Animate’ methods to abstract physics model. Moved FileTile3D, AnimatingTilePanel, and ZapDecorator to these.
  • ZapScroller
    • A lot cleaner. Removed a completely unnecessary layer of complexity.
    • Added the ability to template the buttons. Thanks for the suggestion, Atul.
  • WPF Set
  • General
    • A bunch of renaming of namespaces. Most of the new stuff will exist under J832.Wpf

As always, the SVN location has been updated. Patches are always welcome. (I've had one taker on this. Very cool to do an apply patch. Would love to do it again.)

Enjoy and happy hacking!

Tuesday, February 5, 2008

Xaml Serialization with WCF

So I'm reading RESTful Web Services and I got inspired. Sounds like a great way to expose data on the web.

I've heard great things about WCF support for REST, with their new WebGet attribute and such.

So I fire up Visual C# Express and get hacking.

Amazing what one can do in 54 lines of code.

using System;
using System.ServiceModel;
using System.ServiceModel.Web;
 
namespace J832
{
class Program
{
static void Main(string[] args)
{
Time time = new Time();
 
using (WebServiceHost host = new WebServiceHost(time, new Uri("http://localhost:8080/")))
{
host.AddServiceEndpoint(typeof(ITime), new WebHttpBinding(), "time");
host.Open();
 
Console.WriteLine("enter to close...");
Console.ReadLine();
}
}
}
 
[ServiceContract]
public interface ITime
{
[OperationContract, WebGet]
DateTimeCount GetTime();
}
 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Time : ITime
{
public DateTimeCount GetTime()
{
return new DateTimeCount(DateTime.Now, m_count++);
}
 
private int m_count;
}
 
[Serializable]
public class DateTimeCount
{
public DateTimeCount(DateTime now, int count)
{
Now = now;
Count = count;
}
 
public DateTime Now { get; set; }
public int Count { get; set; }
}
}
 

And we open a browser to http://localhost:8080/time/GetTime:

<DateTimeCount xmlns="http://schemas.datacontract.org/2004/07/J832" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<_x003C_Count_x003E_k__BackingField>0</_x003C_Count_x003E_k__BackingField>
<_x003C_Now_x003E_k__BackingField>2008-02-04T23:28:21.987561-08:00</_x003C_Now_x003E_k__BackingField>
</DateTimeCount>

Isn't that *cough* *choke* pretty *gag*.

I suddenly had a flash of nostalgia...of longing...for Xaml.

Xaml: that wonderful language where document-object mapping is implicit, trivial, and human-understandable.

(I'd love to link to Our 7 Goals of Xaml introduction but the link is dead. Help, Rob?)

Thankfully, XamlWriter is publicly available and WCF is insanely, gratuitously, wonderfully extensible.

  • WCF services have endpoints.
  • Endpoints have contracts.
  • Contracts have operations.
  • Operations have behaviors.
  • Behaviors have formatters.
  • Formatters can have custom messages--for instance, XamlMessage.

Thanks to Maheshwar Jayaraman for the post (and sample) on his old blog that got me started.

The code is a bit longer, but it's mostly boiler plate:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Windows.Markup;
using System.Xml;
 
[assembly: XmlnsDefinition("http://schemas.j832.com/demo/2008", "J832")]
 
namespace J832
{
class Program
{
static void Main(string[] args)
{
Time time = new Time();
 
using (WebServiceHost host = new WebServiceHost(time, new Uri("http://localhost:8080/")))
{
ServiceEndpoint endPoint = host.AddServiceEndpoint(typeof(ITime), new WebHttpBinding(), "time");
foreach (OperationDescription operationDescription in endPoint.Contract.Operations)
{
operationDescription.Behaviors.Add(new MyOperationBehavior());
}
 
host.Open();
 
Console.WriteLine("enter to close...");
Console.ReadLine();
}
}
}
 
[ServiceContract]
public interface ITime
{
[OperationContract, WebGet]
DateTimeCount GetTime();
}
 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Time : ITime
{
public DateTimeCount GetTime()
{
return new DateTimeCount(DateTime.Now, m_count++);
}
 
private int m_count;
}
 
[Serializable]
public class DateTimeCount
{
public DateTimeCount(DateTime now, int count)
{
Now = now;
Count = count;
}
 
public DateTime Now { get; set; }
public int Count { get; set; }
}
 
public class MyOperationBehavior : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
 
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
 
public void ApplyDispatchBehavior(
OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
dispatchOperation.Formatter = new MyMessageFormatter();
}
 
public void Validate(OperationDescription operationDescription) { }
}
 
public class MyMessageFormatter : IDispatchMessageFormatter
{
public void DeserializeRequest(Message message, object[] parameters) { }
 
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
return new XamlMessage(result);
}
}
 
public class XamlMessage : Message
{
public XamlMessage(object value){ Value = value; }
 
public override MessageHeaders Headers
{
get { return new MessageHeaders(MessageVersion.None); }
}
 
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
XamlWriter.Save(Value, writer);
}
 
public override MessageProperties Properties{ get{ return new MessageProperties(); } }
 
public override MessageVersion Version{ get{ return MessageVersion.None; }}
 
public object Value { get; private set; }
}
}

And (drumroll) the output from http://localhost:8080/time/GetTime:

<DateTimeCount Now="2008-02-04T23:53:18.884273-08:00" Count="14" xmlns="http://schemas.j832.com/demo/2008"/>

Isn't that pretty? The XmlnsDefinition assembly attribute is the icing that gives you the pretty xmlns.

Do other folks love Xaml? Do you wish it was available outside PresentationFramework.dll?

Let me know. I'm thinking of starting a campaign.

Hear that, Rob? :-)


kick it on DotNetKicks.com