Friday, December 30, 2011

Drawing tool story: Drawing a sine or cosine curve

Introduction

I am posting a series of article of where I am demonstrating the building of a basic drawing tool. If you are interesting in reading the previous post you can read here

Today I am going to show you guys how to draw a sine or cosine curve, Bellow I have shared a screenshot to let the user know what I am up to. In the bellow drew 9 sine curve on various values for xmin and ymin.

image

I have putdown the code in a single class named “CustomLine” the whole code is given bellow and no need farther explanation, as the class is pretty simple and any one can understand it quickly. If anyone need any explanation please drop a comment, I would more than happy to edit the post to add explanation section.

CustomLine code listing

public class CustomLine
{
private double xmax = 6.5;
private double ymax = 1.1;
private Polyline _pl;
private readonly Canvas _graphControl;

public CustomLine(Canvas graphControl)
{
Ymin = -1.1;
_graphControl = graphControl;
_graphControl.SizeChanged += GraphControlSizeChanged;
Init();
_pl = new Polyline();
}

public bool IsCoSine { get; set; }

public bool Autoscale { get; set; }

public SolidColorBrush Stroke { get; set; }

public List<Point> CurvePoints { get; set; }

public double StrokeThickness { get; set; }

public double Width { get; set; }

public DoubleCollection StrokeDashArray { get; set; }

public int PointLength { get; set; }

public int StartLocation { get; set; }

public double Xmin { get; set; }

public double Ymin { get; set; }

public double Opacity { get; set; }

public bool ShowEffect { get; set; }

public Effect LineEffect { get; set; }

#region Private Functions

private void GraphControlSizeChanged(object sender, SizeChangedEventArgs e)
{
if (Autoscale)
{
CurvePoints.Clear();
DrawSine();
}
}

private void DrawLine()
{
if (IsCoSine == false)
{
DrawSine();
}
else
{
DrawCosine();
}
}

private void Init()
{
CurvePoints = new List<Point>();
Stroke = Brushes.Black;
Width = GetGraphWidth();
StrokeThickness = 2;
StrokeDashArray = null;
PointLength = 70;
StartLocation = 1;
Xmin = 0.1;
Opacity = 1;
ShowEffect = true;
LineEffect = new BlurEffect(){Radius = 2};
}

private void DrawCosine()
{
if (_pl != null)
_graphControl.Children.Remove(_pl);

for (var i = StartLocation; i < PointLength; i++)
{
var x = i / 5.0;
var y = Math.Cos(x);
var curvePoint = GetCurvePoint(new Point(x, y));
CurvePoints.Add(curvePoint);
}

if (_pl != null)
{
_pl.Width = GetGraphWidth();
_pl.Stroke = Stroke;
if (ShowEffect)
{
_pl.Effect = LineEffect;
}
_pl.Opacity = Opacity;
_pl.Points = new PointCollection(CurvePoints);
_graphControl.Children.Add(_pl);
}
}

private void DrawSine()
{
if (_pl != null)
_graphControl.Children.Remove(_pl);

for (var i = StartLocation; i < PointLength; i++)
{
var x = i / 5.0;
var y = Math.Sin(x);
var curvePoint = GetCurvePoint(new Point(x, y));
CurvePoints.Add(curvePoint);
}

if (_pl != null)
{
_pl.Width = GetGraphWidth();
_pl.Stroke = Stroke;
if (ShowEffect)
{
_pl.Effect = LineEffect;
}
_pl.Opacity = Opacity;
_pl.Points = new PointCollection(CurvePoints);
_graphControl.Children.Add(_pl);
}
}

private Point GetCurvePoint(Point pt)
{
var x = (pt.X - Xmin) * GetGraphWidth() / (xmax - Xmin);
var y = GetGraphHeight() - (pt.Y - Ymin) * GetGraphHeight() / (ymax - Ymin);
return new Point { X = x, Y = y };
}

private double GetGraphHeight()
{
return _graphControl.ActualHeight;
}

private double GetGraphWidth()
{
return _graphControl.ActualWidth;
}

#endregion

public void Draw()
{
DrawLine();
}
}


customline uses


Bellow the uses is given, note that I have used a canvas as graph control where any drawing surface can be used, but I feel comfortable as it uses basic functionalities of a drawing surface.


private void DrawPoliLineClick(object sender, RoutedEventArgs e)
{
var line = new CustomLine(GraphControl)
{
Stroke = new SolidColorBrush(Colors.Black),
Xmin = _xmin, Ymin = _ymin ,Opacity = 0.5
};
line.Draw();
_xmin += 0.2;
_ymin += -0.1;
}


Summery


In this short article we have seen how we can use a sine wave or cosine wave curve in WPF. Hope this would help someone some day. I would continue to list lots of drawing and interesting stuff regarding WPF drawing both in 2D and 3D in future post. Until next time bye bye.

Friday, December 23, 2011

Convert anything in online-convert

I was working on a html5 video player dialog in one of my project and I needed some sample video, After few minutes of research I found this awesome site which would help developers a lot when we in need of different file format of a same file.

image

Here is the direct link for the site. http://www.online-convert.com/. I used in case of converting videos. I hope everyone would be able to find something useful here.

Thursday, December 15, 2011

How to build xaml icons using basic objects?

introduction

Hi, I am no designer but some time we have to make some simple objects that can be used as icons, in one of my project I had to make some quick and rusty icons, didn’t know what to do then use some of the xaml’s basic objects to create icons, the screen shot bellow shows 4 icons that I made. The icons are not that much impressive but not that much bad either.
image
This give me lot of confidence on making xaml basic objects. Bellow I have shared the xaml markup that is been used to icon 3 and 4 from left to right.

xaml for icon of with x and y

<Style x:Key="button2Style" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Rectangle StrokeThickness="0.5" Stroke="#232323" Cursor="Hand">
                        <Rectangle.Fill>
                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                <GradientStop Color="Silver" Offset="0.0" />
                                <GradientStop Color="Gray" Offset="1.0" />
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock Padding="5,4" Grid.Column="0">X</TextBlock>
                        <TextBlock Padding="5,4" Grid.Column="1">Y</TextBlock>
                    </Grid>
                    <Rectangle Width="0.5" Fill="Black" HorizontalAlignment="Center"></Rectangle>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

xaml for icon of three black box

<Style x:Key="button3Style" TargetType="Button">
        <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Rectangle StrokeThickness="0.5" Stroke="#232323" Cursor="Hand">
                        <Rectangle.Fill>
                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                <GradientStop Color="Silver" Offset="0.0" />
                                <GradientStop Color="Gray" Offset="1.0" />
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <Canvas>
                        <Rectangle StrokeThickness="0.5" Stroke="#232323" Width="12.5" 
                        Height="7" Fill="#696969" Margin="4,4,0,0">
                        </Rectangle>
                        <Rectangle StrokeThickness="0.5" Stroke="#232323" Width="12.5" 
                        Height="7" Fill="#696969" Margin="19,4,0,0">
                        </Rectangle>
                        <Rectangle StrokeThickness="0.5" Stroke="#232323" Width="12.5" 
                        Height="7" Fill="#696969" Margin="4,14,0,0">
                        </Rectangle>
                        <TextBlock Margin="20,2.5,0,0" Foreground="#232323" Padding="0" 
                        FontSize="15">...</TextBlock>
                    </Canvas>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Not bad right?. Yes using basic objects and effects we can make good looking objects that can be used as reusable objects. Note that I have used gradient effect and just few rectangle and text block to build these two icons.
Hope this will help some one, until next time, bye bye.

Friday, December 9, 2011

Drawing tool story: Switching between themes.

Introduction

In previous Drawing tool story series I have discussed about how to draw a simple line from c# code. Previous article can be found here http://munnaondotnet.blogspot.com/2011/11/drawing-tool-story-drawing-simple-line.html. In this short post we are going to take a look at how we can design theme based WPF application. The idea is pretty much same like asp.net theme switch.

Defining the theme

Changing theme is pretty simple we have do define the themes in a folder in our project and then change the themes in runtime by applying resource clear and merge. Bellow I have share a screen shot of solution explorer where its clearly seen that I have two theme in my project “Blend” and “Windows7” these are just names main styling is done in the Theme.xaml file.

image

Always use dynamic resource for themed application

For each instance of UI element that we want to style we can either add style or perhaps apply default look in the Theme.xaml so that it affect whole application. Bellow I have given a window xaml where its shown Lots of window element’s style is set to dynamic resource. This is the main trick of a themed application, if we apply static  resource this would require a direct reference of the style, where as in dynamic reference we don’t need it, the style may or may not be defined.

In case of dynamic resource style binding If any style is been defined with the style name that will be applied other wise if any default style is been found that would be applied.

<Window x:Class="WD.Shell.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="600" MinWidth="600" MinHeight="450">
<DockPanel Style="{DynamicResource WindowStyle}">
<Menu DockPanel.Dock="Top">
<MenuItem Header="File"></MenuItem>
</Menu>
<Border BorderBrush="#7F7F7F" Margin="20" Padding="2.5" BorderThickness="0.75">
<DockPanel>
<Border x:Name="panelContainer" DockPanel.Dock="Bottom"
Height="40" Margin="0,2,0,0" Style="{DynamicResource ToolPanelStyle}">
<StackPanel Orientation="Horizontal">
<Button Margin="5" Width="35" Height="25" Click="ButtonClick"
Style="{DynamicResource button0Style}"></Button>
<Button Margin="5" Width="35" Height="25" Click="ButtonClick"
Style="{DynamicResource button1Style}" ></Button>
<Button Margin="5" Width="35" Height="25"
Style="{DynamicResource button2Style}"></Button>
<Button Margin="5" Width="35" Height="25"
Style="{DynamicResource button3Style}"></Button>
<Rectangle Margin="10" Width="0.5" Fill="Black"/>
<Rectangle Width="0.5" Fill="Black" Margin="100,10,10,10"/>
<Button Margin="5" Width="80" Height="25"
Command="{Binding ApplyThemeCommand}"
CommandParameter="Blend">Blend</Button>
<Button Margin="5" Width="80" Height="25"
Command="{Binding ApplyThemeCommand}"
CommandParameter="Windows7">Windows 7</Button>
<Rectangle Margin="10" Width="0.5" Fill="Black"/>
</StackPanel>
</Border>
<Border Style="{DynamicResource CanvasContainerStyle}">
<Canvas x:Name="DrawingPanel" ClipToBounds="True"></Canvas>
</Border>
</DockPanel>
</Border>
</DockPanel>
</Window>

 


Change the theme


Last and most important part is switching the theme. Note that in above xaml I have added Two button and those are bind to command. In that command the main trick happens. Bellow the c# code is given.


private void OnApplyThemeCommand(object parameter)
{
var themeName = parameter as string;
var uriString = string.Format("/WD.Shell;component/Theme/{0}/Theme.xaml",themeName);
Dictionary.Source = new Uri(uriString, UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(Dictionary);
}

Here I have changed the theme depending on what button is been pressed. First I have created a url for the theme directory and then clear existing resource the finally apply the new resource. That’s it theme is ready to switch dynamically with the single click on the window button.


Result in blend theme


image


result in windows7 theme


image


Conclusion


In this short article we have seen the basic idea behind themed application.

Thursday, December 1, 2011

A Simple Implementation of ICommand

MVVM pattern is kind of now an essential of building a WPF application, a very rich implementation is  of ICommand is DelegateCommand which came with Microsoft pattern and practice package enterprise library or prism framework also known as “Microsoft composite application block for WPF”. Bellow a simple implementation is given.

public class DelegateCommand : ICommand
{

public delegate void CommandOnExecute(object parameter);
public delegate bool CommandOnCanExecute(object parameter);

private readonly CommandOnExecute _execute;
private readonly CommandOnCanExecute _canExecute;

public DelegateCommand(CommandOnExecute onExecuteMethod,
CommandOnCanExecute onCanExecuteMethod)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}

#region ICommand Members

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

public bool CanExecute(object parameter)
{
return _canExecute.Invoke(parameter);
}

public void Execute(object parameter)
{
_execute.Invoke(parameter);
}

#endregion
}

Bellow I have putdown the use of the DelegateCommand, note that this is not the class of prism, its hand written simple version, just named it DelegateCommand to make it looks like prism’s DelegateCommand.


public ICommand ApplyThemeCommand { get; set; }
public MainWindowPresenter()
{
Dictionary = new ResourceDictionary();
ApplyThemeCommand = new DelegateCommand(OnApplyThemeCommand, CanApplyThemeCommand);
}

private bool CanApplyThemeCommand(object parameter)
{
return true;
}

private void OnApplyThemeCommand(object parameter)
{
//code goes here
}

Xaml use is just like before simple binding with command object.


<Button Margin="5" Width="80" Height="25" 
Command="{Binding ApplyThemeCommand}"
CommandParameter="Blend">Blend</Button>
<Button Margin="5" Width="80" Height="25"
Command="{Binding ApplyThemeCommand}"
CommandParameter="Windows7">Windows 7</Button>

Hope this helps, until next time, Chow.