Verifying if View Exists for specified ViewModel

There might raise situations in your Project where you might be interested to check if the ViewModel specified has a corresponding View defined and gradefully handle the error, than throwing an exception.

Caliburn Micro’s ViewLocator class provides you methods that enables you to do exactly that.

if ((ViewLocator.LocateForModelType(typeof(DummyViewModel), null, null) is TextBlock tb
&& tb.Text.StartsWith("Cannot find", StringComparison.InvariantCultureIgnoreCase)))
{
// View does not exist, Terminate or redirect to another
}
else
{
// View found, redirect to intended one
}
Advertisements

Shaders with HLSL #03: Passing Additional Parameters

In previous parts of this series, we briefly discussed the need for Shaders and created our first Shader Program. In this subsequent part, we would be exploring on passing additional parameters to our Custom Shader.

In previous example, we replaced entire color of applied Control with a single color. What if we need to replace only certain colors, among different colors in the control. We would then need to pass the ‘color to replace’ and ‘new color’ to the Shader.

Step 01 : The Shader

Let’s write our Shader, again with HLSL. We will delve into details soon.

sampler2D input: register(s0);
float4 oldColor : register(c0);
float4 newColor : register(c1);

float4 main(float2 uv:TEXCOORD) : COLOR
{
float4 color = tex2D(input, uv);
if (color.r == oldColor.r && color.b == oldColor.b && color.g == oldColor.g)
{
return newColor;
}
return color;
}

We now have two additional parameters defined in the Line 2 & 3. While it follows the earlier parameter declaration, there is an important difference. For additional (non-image) parameters, we are using the C series registers, which are, as discussed in last post, floating point registers. We have two parameters, both of type float4, which would hold details of ‘old color‘ and ‘new color‘.

float4 oldColor : register(c0);
float4 newColor : register(c1);

In the first line of our main function, we see a new function, which we haven’t seen in previous example.

float4 color = tex2D(input, uv);

tex2D is a texture sampling intrinsic function, which generates a vector from its a sampler and a float2, which holds the two-dimensional texture cordinates at which the sampler is to be sampled. The cordinates (u and v), ranges from (0,0) to (1,1) as one moves from top-left to bottom-right.

In the subsequent code, which is self-explanatory, we compare the RGB values to decide whether we need to replace the color.

Step 02 : The ShaderEffect Class

Having written our Shader, the next obvious step is create our custom class derieved from ShaderEffect. Like in Shader code, we will write the code first and then explore the details.

public class ReplaceColorEffect : ShaderEffect
{
public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ReplaceColorEffect), 0);
public Brush Input
{

get => ((Brush)(GetValue(InputProperty)));
set => SetValue(InputProperty, value);
}

public Color OldColor
{
get { return (Color)GetValue(OldColorProperty); }
set { SetValue(OldColorProperty, value); }
}

public static readonly DependencyProperty OldColorProperty =
DependencyProperty.Register("OldColor", typeof(Color), typeof(ReplaceColorEffect), new PropertyMetadata(Colors.Black,PixelShaderConstantCallback(0)));
public Color NewColor
{
get { return (Color)GetValue(NewColorProperty); }
set { SetValue(NewColorProperty, value); }
}

public static readonly DependencyProperty NewColorProperty =
DependencyProperty.Register("NewColor", typeof(Color), typeof(ReplaceColorEffect), new PropertyMetadata(Colors.Black, PixelShaderConstantCallback(1)));

public ReplaceColorEffect()
{
PixelShader pixelShader = new PixelShader();

pixelShader.UriSource = new Uri(@"E:\App Store\GitHub\anuviswan\LearningPoint\Shaders\ShaderExample001\Shader\ReplaceColor.ps", UriKind.Absolute);

PixelShader = pixelShader;
UpdateShaderValue(InputProperty);
UpdateShaderValue(OldColorProperty);
UpdateShaderValue(NewColorProperty);

}
}

While most of the code is pretty similiar to code in our previous example, ones that needs more attension is discussed below. The most significant difference is the two additional parameters, which are mapped to floating point registers (c registers) and how it is defined in C# code.

public Color OldColor
{
get { return (Color)GetValue(OldColorProperty); }
set { SetValue(OldColorProperty, value); }
}

public static readonly DependencyProperty OldColorProperty =
DependencyProperty.Register("OldColor", typeof(Color), typeof(ReplaceColorEffect), new PropertyMetadata(Colors.Black,PixelShaderConstantCallback(0)));

As observed in the code above, the declaration of dependency properties for c-registers are in the more familiar & conventional syntax, using the DependencyProperty class. What makes it different from normal dependency properties is the PixelShaderConstantCallback parameter of PropertyMetadata class. This tells the compiler that this is a special Dependency property which needs to be mapped to c-registers when communicating with the Shader application.

Rest of the code is pretty self-explanatory and XAML is no different than ones you might have seen countless times, using the dependency properties.

<shadereffects:ReplaceColorEffect OldColor="Red" NewColor="Green"/>

Hit F5 and you can now see your Shader in action. For complete code discussed in this series, please refer to my Github.

Complete Shader with HLSL Series

Shaders with HLSL #02 : Applying Shader to WPF Application

In the first part of series, we wrote our first Shader Program. Now it is time to compile it so that we could use it in our WPF Application.

HLSL Compiler

To compile your HLSL code to a format that could be used with .Net WPF application, you would require the fxc compiler. For Windows 7 and earlier editions, you would need to install DirectX SDK in order to get fxc.exe. For Windows 8 and above, this comes as part of the Windows SDK.

The compiler can found under the location ‘Program Files (x86)\Windows Kits‘. If we had saved our previous written code (from previous part of this series) as RedTint.hlsl, we would need to use following command to compile it.

fxc /T ps_2_0 /E main /Fo RedTint.ps RedTint.hlsl

This would give the necessary ps file, or Pixel Shader file which we could now refer in our WPF Application. Now that we have our Pixel Shader file, we will move on to our WPF application.

Creating our Test Application

We will keep our text application simple. The XAML code is shown below.

<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Normal Button" HorizontalAlignment="Center"/>
<Button Grid.Column="0" Grid.Row="1" Content="Click Me"/>

<Label Grid.Column="1" Grid.Row="0" Content="Button with Shader" HorizontalAlignment="Center"/>
<Button Grid.Column="1" Grid.Row="1" Content="Click Me"/>
</Grid>

Also enclosed is a screenshot of the application. The purpose of our application would be apply our shader to one of the buttons, while leaving the other button untouched, so that we could easily demonstrate the difference (or rather impact of shader). We will also add our RentTint.ps file to our project as a resource.

Defining Custom Effect

To use the compiled shader application, we need to load it to the rendering engine input stream. This is accomplished with the help of ShaderEffect class in .Net. The ShaderEffect base class makes it possible to wrap the HLSL pixel shader and apply them our applications XAML elements.

public class RedTintEffect: ShaderEffect
{
public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(RedTintEffect), 0);
public Brush Input
{

get => ((Brush)(GetValue(InputProperty)));
set => SetValue(InputProperty, value);
}

public RedTintEffect()
{
PixelShader pixelShader = new PixelShader();

pixelShader.UriSource = new Uri(@"path_to_ps_resource", UriKind.Absolute);

PixelShader = pixelShader;
UpdateShaderValue(InputProperty);

}
}

We have defined our custom effect, namely RedTintEffect, derieved from ShaderEffect. Let’s examine the code closely beginging with the constructor.

public RedTintEffect()
{
PixelShader pixelShader = new PixelShader();

pixelShader.UriSource = new Uri(@"path_to_ps_resource", UriKind.Absolute);

PixelShader = pixelShader;
UpdateShaderValue(InputProperty);
}

The first step we need to is to initialize an object of PixelShader (which is a protected member of ShaderEffect class) and refer our ps file using the UriSource property. This would enable the ShaderEffect to communicate with the GPU.

The next step is to create a Dependency Property of Type Brush, calling it “Input”. This is a special property and would contain the input image. There lies a difference in the way we register the Dependency Property as well. Instead of the usual DependencyProperty.Register(), we would be using ShaderEffect.RegisterPixelShaderSamplerProperty() method.

public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(RedTintEffect), 0);
public Brush Input
{

get => ((Brush)(GetValue(InputProperty)));
set => SetValue(InputProperty, value);
}

One of the important points to note in the above code is the final parameter of ShaderEffect.RegisterPixelShaderSamplerProperty() method. The Integer value 0 corresponds to the S0 pixel shader register in our HLSL code. Here is the refered code from HLSL source.

sampler2D input: register(s0);

That’s all we need. We can now go back to our XAML and apply the effect.

Applying Shader

The update code is as follows.

<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Normal Button" HorizontalAlignment="Center"/>
<Button Grid.Column="0" Grid.Row="1" Content="Click Me"/>

<Label Grid.Column="1" Grid.Row="0" Content="Button with Shader" HorizontalAlignment="Center"/>
<Button Grid.Column="1" Grid.Row="1" Content="Click Me">
<Button.Effect>
<shadereffects:RedTintEffect/>
</Button.Effect>
</Button>
</Grid>

We have added our newly added custom Effect to one of the button. Let’s hit F5 and verify our changes.

As observed in the screenshot, the Button to which the Effect was applied has turned Red, while the other Controls remain the same. Do observe that even the Forecolor of Text within the button has turned Red. This is true to our definition of our Shader, since it returns Red irrespective of the input. We will look into more complex scenarios in later posts where we will introduce conditional color changes.

You can access the entire source code described in Part 1 and Part 2 of this series from my Github

Shaders with HLSL #01 : Shaders with HLSL for WPF Developers

Complete Tutorial Series

In this first part of our tutorial, we will briefly enlighten ourselves on key concepts involving shaders and why it is required. We will also write our first shader application, introducing ourself to the HLSL semantics.

What is a Shader ?

Shaders are small programs written to run on the GPU (Graphical Processing Unit) and describes how to render each pixel. Since running parallely on the GPU hardware, they typically produces faster output,compared to having it run on the CPU.
There are mainly two types of Shaders

  • Vertex Shader – Vertex Shader gets the first chance to work on Model, prior to even Rasterizer and is responsible for transforming vertex.
  • Pixel Shader – Pixel Shader comes into pipeline a little later, after Rasterizer and is responsible for determining the final color of a pixel

WPF and Shaders

The huge computing power of modern GPUs ensures complex and graphically rich applications have little impact on performance. Begining with .Net 3.5 SP1, Microsoft introduced hardware accelerated affects for WPF (Effects in WPF, for example Blur Effect and DropShadowEffect) utilizing the power of shaders. We could write our own custom shaders and use them in our WPF applications.

Evolution of HLSL/C

One of the earliest approaches for writing Shaders used assembly language, but soon it was evident that the inherient complexity of Assembly Language was not making it any easier. This lead to development of Cg (C for Graphics) by NVida and HLSL (High Level Shader Language) by Microsoft. Both languages follows a similiar syntax and is closely associated to C Language in syntax and compile shaders for DirectX.

Getting Started with HLSL

Let’s write some code first and then we will go in detail examining the code as well as how to use it in your WPF Application.

sampler2D input: register(s0);

float4 main(float2 uv:TEXCOORD) : COLOR
{
return float4(1.0f, 0.0f, 0.0f, 1.0f);
}

The first line of code represent our input parameters, stored in GPU registers.

sampler2D input: register(s0);

Pixel Shaders rely on GPU registers input, which are high speed storage areas. There are different types of registers, but most of our applications written in C# depends on S and C register1 types. The S registers, also known as Sampler Registers are mainly used for storing input images data2. If we need to pass another Image Source, we could pass it via the register s1. We could pass other arguements to our shaders using the C registers (floating point registers), but for the sake of our first example, we will keep it simple with just a single input parameter, which is our Image data.

The first line of code specifies an input variable input and the register to use for the purpose. It also specifies the input type, which in this case is sampler2D and refers to the image it is being applied to.

The main as one can easily guess, represent the entry point of the shader code. The incoming parameter uv represents the incoming texture cordinates, while the return type float4 represents an RGBA color.

float4 main(float2 uv:TEXCOORD) : COLOR

The body of our first Shader application is pretty simple, it returns a color representing Red.

return float4(1.0f, 0.0f, 0.0f, 1.0f);

Let’s save the above code with extension “hlsl”. In the next part of tutorial we will examine how to compile our HLSL code to ps format, which would be later consumed by our WPF application.


  1. More on Registers : Source : Microsoft 
  2. Image, in this context refers to visual representation of the target control. 

Caliburn.Micro #007 : Bootstrapper with Unity

Unity is one of the most commonly used IOC containers used by developers, and it would be unfair if I don’t include it as a part of the Caliburn.Micro WPF Tutorials (Creating Bootstrappers).  This particular post is dedicated to building bootstrapper for Caliburn.Micro application using Unity as the IoC Container.


The key for creating Bootstrappers for Caliburn.Micro application lies in overriding 4 methods from the BootstrapperBase class. The 4 methods are
  1. Configure
  2. BuildUp
  3. GetInstance
  4. GetAllInstance
The implementation using SimpleContainer and MEF is described in the earlier parts of the Caliburn.Micro Tutorials. Let’s go ahead and implement the Configure method using Unity.
private IUnityContainer _unityContainer;
protected override void Configure()
{
    _unityContainer = new UnityContainer();
    _unityContainer.RegisterInstance<IWindowManager>(new WindowManager());
    _unityContainer.RegisterInstance<IEventAggregator>(new EventAggregator(), new ContainerControlledLifetimeManager());
    //  View Models
    _unityContainer.RegisterInstance<IShellViewModel>(new ShellViewModel());
}
Container using Unity is initialized using the UnityContainer class. RegisterInstance methods are used to register your Classes. For cases, where you need Singletons, you can make use of the ContainerControlledLifeTimeManager as seen in the above example. This place will also hold your ViewModel registrations as well.


Rest of the 3 methods are pretty simple and straightforward to understand.
protected override void BuildUp(object instance)
{
  _unityContainer.BuildUp(instance);
  base.BuildUp(instance);
}
protected override object GetInstance(Type service, string key)
{
  return string.IsNullOrEmpty(key) ? _unityContainer.Resolve(service, key) : _unityContainer.Resolve(service);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
  return _unityContainer.ResolveAll(service);
}
Finally, similar to earlier Bootstrappers, we use the OnStartup Method to invoke the ShellViewModel.

protected override void OnStartup(object sender, StartupEventArgs e)
{
   DisplayRootViewFor<IShellViewModel>();
}

The complete code sample can be accessed at my Github. The bootstrapper template is also included as a part of Caliburn.Micro Template Pack for WPF.

Invoke UIElement’s Focus() Method From ViewModel

One of the things WPF developers often notice is inability to SetFocus on a particular control from the ViewModel. This problem can be however easily resolved using an attached property. Let’s examine the code.

We will begin by writing an attached property, for the purpose of example, named as IsFocused.

public class FocusExtension : DependencyObject
{
    public static bool GetIsFocused(DependencyObject dependencyObject) => (bool)dependencyObject.GetValue(IsFocusedProperty);
    public static void SetIsFocused(DependencyObject dependencyObject, bool value) => dependencyObject.SetValue(IsFocusedProperty, value);
    public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusExtension), new PropertyMetadata(false, IsFocusChanged));
    private static void IsFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
       if ((bool)e.NewValue)
       {
          d as UIElement).Focus();
       }
    }
}

The sole objective of the attached property is to call the Focus() method of the attached UI element when the IsFocused Property Changes. Since the attached property is bindable from ViewModel, we can now set Focus to any control from our View Model. Am using Caliburn.Micro for my MVVM Implementation

View

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Button Grid.Row="0" Grid.Column="0" Content="Set Focus" x:Name="SetFocusOnTextBox1"/>
        <TextBox Grid.Row="0" Grid.Column="1" Text="TextBox 1" ap:FocusExtension.IsFocused="{Binding IsTextBox1Focused}"  />
        <Button Grid.Row="1" Grid.Column="0" Content="Set Focus" x:Name="SetFocusOnTextBox2"/>
        <TextBox Grid.Row="1" Grid.Column="1" Text="TextBox 2" ap:FocusExtension.IsFocused="{Binding IsTextBox2Focused}"  />
        <Button Grid.Row="2" Grid.Column="0" Content="Set Focus" x:Name="SetFocusOnTextBox3"/>
        <TextBox Grid.Row="2" Grid.Column="1" Text="TextBox 3" ap:FocusExtension.IsFocused="{Binding IsTextBox3Focused}"  />
        <Button Grid.Row="3" Grid.Column="0" Content="Set Focus" x:Name="SetFocusOnTextBox4"/>
    </Grid>

ViewModel

public bool IsTextBox1Focused { get; set; }
public bool IsTextBox2Focused { get; set; }
public bool IsTextBox3Focused { get; set; }

public void SetFocusOnTextBox1()
{
   IsTextBox1Focused = true;
   NotifyOfPropertyChange(nameof(IsTextBox1Focused));
}

public void SetFocusOnTextBox2()
{
   IsTextBox2Focused = true;
   NotifyOfPropertyChange(nameof(IsTextBox2Focused));
}

public void SetFocusOnTextBox3()
{
   IsTextBox3Focused = true;
   NotifyOfPropertyChange(nameof(IsTextBox3Focused));
}

SharedSizeGroup: Managing Column Size across Grids

SharedSizeGroup is an underused WPF attribute, but one that can make life lot more easier when design WPF forms with multiple Grids that need to share a column size. Consider the screenshot below. The three pairs of Label and Textbox are in separate grids (with column width set to auto), resulting in an unorganized layout. It would far more better if the column width of first grid resizes itself to width of column in second grid.

Without SharedSizeGroup

You might often have to design more complex scenarios where you would love to retain the column size across Grids. This is where SharedSizeGroup comes into play. Let’s redefine our XAML with the attribute.

<Grid Margin="10,10,10,10">
        <StackPanel Grid.IsSharedSizeScope="True">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="ABC"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="Name"></TextBlock>
                <TextBox Grid.Column="1"/>
            </Grid>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="ABC"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="Full Name"></TextBlock>
                <TextBox Grid.Column="1"/>
            </Grid>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="ABC"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="Last Name"></TextBlock>
                <TextBox Grid.Column="1"/>
            </Grid>
        </StackPanel>
    </Grid>

 
Now the layout looks better organized.

With SharedSizeGroup