Blog Archive

Monday, May 26, 2008

Language Binding for WCF REST Messages


WCF in .Net 3.5 support REST on server side using [WebGet]. But there are no SOAP/WSDL proxy auto-gen tool. In fact, REST messages will come off wire through WebClient and we can use DataContractSerializer to bind back to a CLR object.

namespace GMO
{
[DataContract()]
public class Stock
{
[DataMember]
public double Price { get; set; }
[DataMember]
public string Symbol { get; set; }
public override string ToString()
{
return Price.ToString();
}
}

using Data;
[ServiceContract]
public interface IPostTrade
{
[OperationContract]
[WebGet()]
List<object> GetInstrumentList(string tradeID);

[OperationContract]
[WebGet()]
bool HasSettled(string TradeID,string InstID);

[OperationContract]
[WebGet()]
List<Stock> GetStockHoldings(string BlotterID);

}
}


DataContractSerializer ser = new DataContractSerializer(typeof(List<GMO.Data.Stock>));
WebClient c= new WebClient();
Stream r = c.OpenRead(@"http://localhost:49176/PostTrade.svc/GetStockHoldings?blooterID=0");
List<GMO.Data.Stock> list=(List<GMO.Data.Stock>)ser.ReadObject(r);
listBox1.ItemsSource = list;



Exposing CLR object as WCF REST


Use .Net framework 3.5, we can load CLR objects through WebService Host Factory as WCF REST Message endpoint without any configuration.
Note that we only need one .svc file specifiying Factory and Service CLR class. After that we can just add any new method on the fly to that CLR class and copy paste to Web Service for new functionality.

<%@ ServiceHost Language="C#" Debug="true"
Service="GMO.PostTrade"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
%>

namespace GMO
{
[ServiceContract]
public interface IPostTrade
{
[OperationContract]
[WebGet()]
List<object> GetInstrumentList(string tradeID);

[OperationContract]
[WebGet()]
bool HasSettled(string TradeID,string InstID);

}

public class PostTrade : IPostTrade
{
public List<object> GetInstrumentList(string tradeID)
{
List<Object> list = new List<object>();
for (int i = 0; i < 10; i++)
list.Add("CRD Instrument" + i.ToString() + " for trade ID=" + tradeID);
return list;
}

public bool HasSettled(string TradeID, string InstID)
{
if (InstID=="1" ) return true;
return false;
}


}
}

To access end points added into the CLR class:

http://localhost:49176/PostTrade.svc/GetInstrumentList?TradeID=78
http://localhost:49176/PostTrade.svc/HasSettled?InstID=10
http://localhost:49176/PostTrade.svc/AnyNewMethodAdded?newID=99

Sunday, May 25, 2008

Simple Master-Detail Databinding


In WPF, Listbox can hold IEnumerable while ContentPresneter can display CurrentItem. When both control share the same DataContext, Master detail relationship is established:



public class Stocks : List
{
public Stocks()
{
Add(new Stock("YHOO", 27.90));
Add(new Stock("MSFT", 28.90));
Add(new Stock("GOOG", 179.40));
}
}

public class Stock {
public string Symbol { get; set; }
public double Price { get; set; }
public Stock(string s, double p) {
this.Price = p; this.Symbol = s; }
public override string ToString() { ..}
}


<Window x:Class="MasterDetailWPF.Window1"
xmlns="..."
xmlns:x="..."
...
xmlns:local="clr-namespace:MasterDetailWPF">
<Window.DataContext>
<local:Stocks>
</Window.DataContext>
<Grid>
<ListBox ..
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True">

</ListBox>
<ContentPresenter Content="{Binding}" ..>
<ContentPresenter.ContentTemplate>

<DataTemplate>
<TextBox Text="{Binding Path=Symbol, Mode=Default}" />
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</Window>



Wednesday, May 21, 2008

Tilt User Interface for eye-ball



Before WPF, UI is layed out on a flat plane, limiting the number of UI elements. Some information just need eye-ball and therefore can be tilted to save space.
Here is the code to do that using SkewTransform:


<Grid Margin="8,-73,0,0" Name="grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<DockPanel Margin="8,190,0,28" Name="viewbox1">

<Image Source="c:\working\1.jpg" Margin="0,0,0,0" Name="image1" Height="163" VerticalAlignment="Top" Width="141" />
<TextBox Height="164" Margin="14,0,16,64" Name="textBox1" VerticalAlignment="Bottom" />

<DockPanel.RenderTransform>
<SkewTransform AngleX="0" AngleY="-40" />
</DockPanel.RenderTransform>
</DockPanel>
<ListBox Grid.Column="1" Margin="0,73,0,29">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
</ListBox>
<ListBox Grid.Column="2" Margin="2,75,-2,30">
<ListBoxItem>1
<ListBoxItem>2
<ListBoxItem>3
<ListBox.RenderTransform>
<SkewTransform CenterX="0" CenterY="0" AngleX="0" AngleY="40" />
</ListBox.RenderTransform>
</ListBox>

Collection View


Data should be separated out from UI Elements for data binding purposes. In fact, Sorting, Grouping, selected changed event ( as in IBindingList) are better handled in View ( such as DataView and ListCollectionView). Here is a simple usage of Collection View in WPF:


public class Stock
{
public string Symbol { get; set; }
public double Price { get;set;}
public Stock(string s, double p)
{
this.Price = p;
this.Symbol = s;
}

public override string ToString()
{
return Symbol + " " + Price;
}
}

List<Stock> stocks = new List<Stock>();
stocks.Add(new Stock("YHOO", 27.90));
stocks.Add(new Stock("MSFT", 28.90));
stocks.Add(new Stock("GOOG", 179.40));
ListCollectionView cv = new ListCollectionView(stocks);
cv.SortDescriptions.Add(new SortDescription("Symbol", ListSortDirection.Ascending));
Binding b = new Binding();
b.Source = cv;
this.listBox1.SetBinding(ListBox.ItemsSourceProperty, b);


Monday, May 19, 2008

Control template vs. Data Template

In the following Example, both Control Template and Data Template will fill ListBox using List Data. But Control Template disable ListBox Selection.

<Window.Resources>
<!--<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <TextBlock Text="{Binding Path=Symbol}"></TextBlock> </ControlTemplate>
</Setter.Value>
</Setter>
</Style>-->
<ObjectDataProvider x:Key="Stocks" ObjectType="{x:Type data:Stocks}" />
<DataTemplate x:Key="ShowStock">
<TextBlock Text="{Binding Path=Symbol}">

</DataTemplate>
</Window.Resources>
<Grid Height="182" Width="240"> <Grid.RowDefinitions> <RowDefinition> <RowDefinition> </Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Source={StaticResource Stocks}}" Name="StockList1" Grid.Row="0" ItemTemplate="{Binding Source={StaticResource ShowStock}}" />
<ListBox ItemsSource="{Binding Source={StaticResource Stocks}}" Name="StockList2" Grid.Row="1" />
</Grid>

Use Style to Add Control Template

WPF make is very easy to do "owner-drawl" by Control Template

<Window.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<DockPanel>
<TextBlock TextTrimming="CharacterEllipsis" Width="150" Text="{TemplateBinding Content}" Foreground="Red"/>
<Image Source="c:\working\Test1.jpg" Width="20" Height="20"/>
<DockPanel> </ControlTemplate> </Setter.Value>
</Setter>
</Style>
</Window.Resources> <StackPanel Margin="30">
<ListBox>
<ListBoxItem>Test this /ListBoxItem>
</ListBox>
</StackPanel>