Tuesday, March 31, 2009

DataBinding to App.Settings values

.Net 2.0 introduced this feature which helps to store and retrieve application specific settings very easily.You can easily create Settings through the visual editor.If we want to access them in code we can just use the Properties.Settings.Default object directly.The Default object will have all the properties which we had created at design time.
Showing ConnectionString entry in Messagebox
MessageBox.Show(Properties.Settings.Default.ConnectionString);


It is very easy.Lets learn how this can be binded in to a WPF TextBox.

First make a namespace reference to the Properties namespace.If your application name is WpfApplication1 it is xmlns:props=”WpfApplication1.Properties”.

Then in the Binding set source as the Default property available in the class Settings.Since it is static you have to use the x:Static binding extension.

Finally the path is ConnectionString which is the settings entry name.

Putting it altogether.


<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.Window1"
x:Name="Window"
xmlns:props="clr-namespace:WpfApplication1.Properties">
<Grid x:Name="LayoutRoot">
<TextBox  HorizontalAlignment="Left"  VerticalAlignment="Top"
Text="{Binding Source={x:Static props:Settings.Default},Path=ConnectionString}">
</TextBox>
</Grid>
</Window>


So enjoy WPF data binding to Properties.Settings.Default.

Tuesday, March 24, 2009

Writing custom Pixel shader effects.

What are Pixel shaders

Pixel shaders are programs which operates on each pixel before displaying in the screen.Pixel shaders are not part of Silverlight or WPF.They are more related to the Graphics cards and DirectX.They use a language called HLSL (High Level Shader Language) for programming.It has more similarities to C than C#.More details on HLSL is available here.

Coding Pixel Shader : Negative.Fx

Coding in HLSL refers some registers and all.Here is the code for a Negative Effect.

sampler2D implicitInput : register(s0);

float4 PS(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(implicitInput, uv);

float4 result;

result.r=1-color.r;
result.g=1-color.g;
result.b=1-color.b;
result.a=color.a;

return result;
}



We are getting the color value of pixel in float4 located at uv and returning a color (result)which is inverse of the given color.

Compiling a Pixel Shader

The extension of the Pixel shader files will be .FX.We need to have DirectX SDK installed in our machine in order to compile HLSL (*.fx) source code to *.ps bytecode that can be loaded using Silverlight’s PixelShader class. Fxc.exe is the HLSL compiler used to compile *.fx HLSL shader files. The following command shows how to compile Negative.fx:


Current folder : [Install drive]:\Program Files\Microsoft DirectX SDK (November 2008)\Utilities\bin\x86 (Change the month according to the version you have)


fxc.exe /T ps_2_0 /E PS /FoNegative.ps Negative.fx

/T ps_2_0 :Compiles against the ps_2_0 target pixel shader level that WPF currently supports
/E PS : Marks the function 'PS' as the entry point
/FoNegative.ps Negative.fx : Negative.fx as input and output to Negative.ps. Note that there is no space between /Fo and Greyscale.ps

The command above can be used as pre-build event of a Visual Studio project to automate the build process.


Creating Custom Shader Effect class


Add the output .ps file as Resource in the project.Once we add the .ps file we can start writing the .Net interface class for that.It is derived from the ShaderEffect class and we need to add some things there.See the below code.



public class Negative : ShaderEffect
{
private static PixelShader _pixelShader = new PixelShader()
{
UriSource = new
Uri("pack://application:,,,/WpfCustomEffect;component/Negative.ps",
UriKind.RelativeOrAbsolute)
};

public static readonly DependencyProperty InputProperty =
ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(Negative), 0);
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}

public Negative()
{
this.PixelShader = _pixelShader;
UpdateShaderValue(InputProperty);
}
}



PixelShader is the protected property in ShaderEffect class and that should be initialized with a new instance which refers to our .ps file.Then we creates a dependency property which is of type Brush and associates to the shader.Creating dependency property is a bit different here.We need to use ShaderEffect.RegisterPixelShaderSamplerProperty method in order to create the DP.


Using Custom Pixel Shader


We can use the new Effect from either XAML or C# code behind.



<Image x:Name="img"
Source="Autumn.jpg">
<Image.Effect>
<effect:Negative />
</Image.Effect>
</Image>
<Button Grid.Row="1"
Click="Button_Click"
Content="Click to change">
<Button.Effect>
<effect:Negative />
</Button.Effect>
</Button>




private void Button_Click(object sender, RoutedEventArgs e)
{
if (img.Effect == null)
{
img.Effect = new Negative();
}
else
{
img.Effect = null;
}
}



Sample can be downloaded from here.

Monday, March 16, 2009

ObservableDictionary

The existing Dictionary is not a friend of WPF in the case of databinding.ie WPF can't listen on it's CollectionChanged and hence the UI won't get updated if you add or remove anything to or from the dictionary.
What I was doing is to create a new class with 2 properties (Key and Value) and it's Collection class derived from ObservableCollection.

For example in a card game, if we want to store the 'Play' keyed by Player object (like Dictionary<player,card>),we have to create a class PlayCard which have Player and Card properties and it's collection class PlayCardCollection derived from ObservableCollection.

This is very much time consuming.Here Dr.WPF has provided one implementation of ObservableDictionary which has the capabilities to provide CollectionChanged.Now it is very easy to have ObservableDictionary<player,card>.
Thanks to Dr.WPF for such a great work.

Thursday, March 12, 2009

WPF rendering steps

Here explains the rendering pipeline of WPF visual objects.
If we take a Visual object in WPF ,the rendering takes place as follows
  1. Render all children.
  2. Process OpacityMask.
  3. Process Opacity
  4. BitmapEffect
  5. Clip geometry
  6. GuidelineSet
  7. Transforms

More details here