Friday, June 29, 2012

Logging using Log4Net in WPF

log4net is best logging framework available for .Net.

Let's start with step by step, how to log error in your application.

Step 1:first download latest log4net dll.

click Log4Net dll to download and add reference in your project.

Step 2: Create log4net.config application configuration file for configuration settings.

FileName : log4net.config

there are many ways to create log file and message/error format.

I have created 2 formats, one for create log file within folder, one for create log file directly within Debug folder.

Format 1 : Create folder named Log and create log file dynamically date wise and save in Debug folder.

<log4net debug="true">
    <appender name="RollingLogFileAppender" 
                type="log4net.Appender.RollingFileAppender">
      <file value="Logs\log" />
      <staticLogFileName value="false"/>
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <datePattern value=" yyyy-MM-dd&quot;.xml&quot;"/>
      <layout type="log4net.Layout.PatternLayout">        
        <!--<param name="ConversionPattern" 
               value="%d [%t] %-5p %c %m%n" />-->
        <conversionPattern 
           value="%date [%thread] %-5level %logger ==> %message%newline"/>
      </layout>
    </appender>

    <root>
      <level value="INFO" />
      <appender-ref ref="RollingLogFileAppender" />
      <appender-ref ref="AdoNetAppender" />
    </root>
  </log4net>

Format 2 : Create log file named hirenlog.txt and save in Debug folder.

<log4net debug="true">
  <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
    <param name="File" value="hirenlog.txt" />
    <param name="AppendToFile" value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="Header" value="[Header]\r\n" />
      <param name="Footer" value="[Footer]\r\n" />
      <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
    </layout>
  </appender>
  <root>
    <level value="INFO" />
    <appender-ref ref="LogFileAppender" />
  </root>
</log4net>
 
Step 3: Right click on log4net.config file and go to properties and set 
"Copy to Output Directory" property value to "Copy if newer" as highlighted in below image.


Step 4: Open AssemblyInfo.cs file from properties and add below line at end of file.

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]


Step 5 : Create Logger Class.

    public interface ILogger
    {
        void LogException(Exception exception);
        void LogError(string message);
        void LogWarningMessage(string message);
        void LogInfoMessage(string message);
    }
    public class Logger : ILogger
    {      
        private static ILog log = null; 
        static Logger()
        {
            //var log4NetConfigDirectory = 
            //AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
            //var log4NetConfigFilePath = Path.Combine(log4NetConfigDirectory, "log4net.config");
            //log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFilePath));
            log = LogManager.GetLogger(typeof(Logger));
            log4net.GlobalContext.Properties["host"] = Environment.MachineName;
        }
        public Logger(Type logClass)
        {
            log = LogManager.GetLogger(logClass);
        }

        #region ILogger Members
        public void LogException(Exception exception)
        {
            if (log.IsErrorEnabled)
                log.Error(string.Format(CultureInfo.InvariantCulture, "{0}", exception.Message), exception);
        }
        public void LogError(string message)
        {
            if (log.IsErrorEnabled)
                log.Error(string.Format(CultureInfo.InvariantCulture, "{0}", message));
        }
        public void LogWarningMessage(string message)
        {
            if (log.IsWarnEnabled)
                log.Warn(string.Format(CultureInfo.InvariantCulture, "{0}", message));
        }
        public void LogInfoMessage(string message)
        {
            if (log.IsInfoEnabled)
                log.Info(string.Format(CultureInfo.InvariantCulture, "{0}", message));
        }
        #endregion
    }

Above class configures log4net using xml file (log4net.config) and creates instance of ILog, now you will use this class for logging errors from ViewModels.

Step 6 : In you ViewModel Initialize ILogger class and logs errors.

  internal class MainWindowViewModel
  {
     ILogger logger = new Logger(typeof(MainWindowViewModel));
     public MainWindowViewModel()
     {
        logger.LogError("Error while downloading data"); 
     } 
  }

so, this is simple way to logs you error and exception details.

Thursday, June 28, 2012

Split Comma Seperated String using XML in Sql Server

DECLARE @strDeviceData varchar(MAX) = '1:1,1:0,2:0,2:1'
DECLARE @X xml
DECLARE @split char(1)
SET @split=','
SELECT @X=CONVERT(xml,'<root><h>' + REPLACE(@strDeviceData,@Split,'</h><h>') + '</h></root>')
SELECT [DeviceInfo] = T.c.value('.','varchar(20)')
FROM @X.nodes('/root/h') T(c)

When you run query, you will get following output.

 

Thursday, June 21, 2012

Dynamically Creating Pie/Bar Chart in C# WinForms

Chart control is available in Data Category of ToolBox in Windows Form Application.

If not available then

First Download Microsoft Chart Controls for Microsoft .NET Framework 3.5  and install it. 



After that, right click on ToolBox, select Choose Items and then select namespaces checked in above image.

now Chart control is added into your toolbox.


Add Reference System.Windows.Forms.DataVisualization
Create Chart

Step 1 : Add New Windows Form in your Application.


Add Two panels in your Form, one for Pie chart and one for Bar chart as in shown below image.




Step 2 : Go to Code Behind (C#) and initialize chart controls.

public partial class Form1 : Form
    {
        Chart pieChart;
        Chart barChart;
        public Form1()
        {
            InitializeComponent();
            InitializeChart();
        }
        private void InitializeChart()
        {

            this.components = new System.ComponentModel.Container();
            ChartArea chartArea1 = new ChartArea();
            Legend legend1 = new Legend() 
              { BackColor = Color.Green, ForeColor = Color.Black, Title = "Salary" };
            Legend legend2 = new Legend() 
              { BackColor = Color.Green, ForeColor = Color.Black, Title = "Salary" };
            pieChart = new Chart();
            barChart = new Chart();

            ((ISupportInitialize)(pieChart)).BeginInit();
            ((ISupportInitialize)(barChart)).BeginInit();

            SuspendLayout();

            //===Pie chart
            chartArea1.Name = "PieChartArea";
            pieChart.ChartAreas.Add(chartArea1);
            pieChart.Dock = System.Windows.Forms.DockStyle.Fill;
            legend1.Name = "Legend1";
            pieChart.Legends.Add(legend1);
            pieChart.Location = new System.Drawing.Point(0, 50);

            //====Bar Chart
            chartArea1 = new ChartArea();
            chartArea1.Name = "BarChartArea";
            barChart.ChartAreas.Add(chartArea1);
            barChart.Dock = System.Windows.Forms.DockStyle.Fill;
            legend2.Name = "Legend3";
            barChart.Legends.Add(legend2);

            AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            //this.ClientSize = new System.Drawing.Size(284, 262);           
            this.Load += new EventHandler(Form1_Load);
            ((ISupportInitialize)(this.pieChart)).EndInit();
            ((ISupportInitialize)(this.barChart)).EndInit();
            this.ResumeLayout(false);

        }

        void Form1_Load(object sender, EventArgs e)
        {
            LoadPieChart();
            LoadBarChart();
        }
} 

Step 3 : Create Methods to Create Pie and Bar charts and load into Panels.
 
        void LoadPieChart()
        {
            pieChart.Series.Clear();
            pieChart.Palette = ChartColorPalette.Fire;
            pieChart.BackColor = Color.LightYellow;
            pieChart.Titles.Add("Employee Salary");
            pieChart.ChartAreas[0].BackColor = Color.Transparent;
            Series series1 = new Series
            {
                Name = "series1",
                IsVisibleInLegend = true,
                Color = System.Drawing.Color.Green,
                ChartType = SeriesChartType.Pie
            };
            pieChart.Series.Add(series1);
            series1.Points.Add(70000);
            series1.Points.Add(30000);
            var p1 = series1.Points[0];
            p1.AxisLabel = "70000";
            p1.LegendText = "Hiren Khirsaria";
            var p2 = series1.Points[1];
            p2.AxisLabel = "30000";
            p2.LegendText = "ABC XYZ";
            pieChart.Invalidate();
            pnlPie.Controls.Add(pieChart);
        }
        void LoadBarChart()
        {
            barChart.Series.Clear();
            barChart.BackColor = Color.LightYellow;           
            barChart.Palette = ChartColorPalette.Fire;
            barChart.ChartAreas[0].BackColor = Color.Transparent;
            barChart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
            barChart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
            Series series = new Series
            {
                Name = "series2",
                IsVisibleInLegend = false,
                ChartType = SeriesChartType.Column
            };
            barChart.Series.Add(series);
            series.Points.Add(70000);
            var p1 = series.Points[0];
            p1.Color = Color.Red;
            p1.AxisLabel = "Hiren Khirsaria";
            p1.LegendText = "Hiren Khirsaria";
            p1.Label = "70000";
           
            series.Points.Add(30000);
            var p2 = series.Points[1];
            p2.Color = Color.Yellow;
            p2.AxisLabel = "ABC XYZ";
            p2.LegendText = "ABC XYZ";
            p2.Label = "30000";
            barChart.Invalidate();
            
            pnlBar.Controls.Add(barChart);
        }


Above methods create Pie chart and Bar chart, that display employee salary.

Below image shows final result ( showing Pie and Bar charts)


Monday, June 4, 2012

Modify XML Attribute value in SQL Server


     DECLARE @xmlData xml
    SET @xmlData=convert(xml,
    ' <Data>
      <Employee>
        <Item Section="1" primaryKeyId="11" name="HD1">
          <Details>
            <Column surname="Khirsaria" firstname="Hiren" salary="10000" />
          </Details>
        </Item>
        <Item Section="2" primaryKeyId="12" name="HD2">
          <Details>
            <Column surname="AAA" firstname="aaa"  salary="8000" />
          </Details>
        </Item>
        <Item Section="2" primaryKeyId="14" name="HD3">
          <Details>
            <Column surname="BBB" firstname="bbb"  salary="8000" />
          </Details>
        </Item>
      </Employee>
    </Data>
    ')

SELECT @xmlData

SET @xmlData.MODIFY('
  replace value of (/Data/Employee/Item[1]/Details/Column/@salary)[1]
  with     "20000" ')


set @xmlData.MODIFY(' replace value of (/Data/Employee/Item[2]/Details/Column/@surname)[1]   with     "Hello" ')

SELECT @xmlData

Saturday, June 2, 2012

Shapes and Drawing in WPF/Silverlight

In WPF/Silverlight Shape object is used to draw a shapes like (Line,Rectangle,Ellipse,Polygon etc.)

In this post we go through how to create and use ready to use shape and create custom shape using path property.

Shape object contains three common properties listed below.

1. Fill      :- This property is used to fill shape with color.
2. Stroke :- This property describes border color for the shape.
3. StokeThickness :- This property set shape border thickness.

Now, we will discuss various shapes into details.

Line

Line element is used to draw a line between two points. there are four attributes to draw a line (X1,Y1,X2,Y2) represents start point and end point for X and Y co-ordinates of line.


            <Line Stroke="Red" HorizontalAlignment="Center"
                  StrokeThickness="5"
                  X1="0"
                  Y1="0"
                  X2="200"
                  Y2="100" />


Ellipse

This shape create ellipse to circle in specified width and height.
 


            <Ellipse Height="80"
                     Width="200"
                     StrokeThickness="5"
                     Stroke="Red"
                     Fill="Black" />

Rectangle
This shape draw a rectangle.

 
       <Grid Grid.Row="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5*" />
                <ColumnDefinition Width="5*" />
            </Grid.ColumnDefinitions>
            <Rectangle Width="120"
                       Grid.Column="0"
                       Height="80"                      
                       Stroke="Red"
                       StrokeThickness="5"
                       Fill="Black" />
            <Rectangle Width="120" Grid.Column="1"
                       Height="80"
                       RadiusX="25"
                       RadiusY="25"
                       Stroke="Red"
                       StrokeThickness="5"
                       Fill="Black" />
       </Grid>

As shown in above figure, first is simple rectangle and second figure indicates rounded rectangle. To draw rounded rectangle we have to set two more properties (RadiusX and RadiusY) for round corner.

Polyline

This shape is used draw a series of connected strait line.
  
            <Polyline Points="0,50 20,0 40,50 60,0 80,50 100,0 120,50 -4,50"
                      Stroke="Blue"
                      StrokeThickness="10"
                      Canvas.Left="75"
                      Canvas.Top="50" /> 

Polygon

This shape i used to draw a polygon, which is a connected series of lines that form a closed shape.
Following examples shows how to creates different types of shapes using polygon

Example 1 :


                <Polygon Points="0,50 0,100 100,100 100,10 70,50"
                         Fill="Magenta"
                         Stroke="Black"
                         StrokeThickness="3" />

Example 2 :

           <Grid Grid.Column="1">
                <Polygon Fill="LightBlue"
                         Points="26,4 0,8 0,115 4,120 4,12 30,8 26,4"
                         Stroke="Gray"
                         StrokeDashArray="0" />
                <Polygon Fill="LightCoral"
                         Points="30,8 4,12 4,120 115,110 115,82 30,90"
                         Stroke="Yellow" />
                <Polygon Fill="LightBlue"
                         Points="115,82 30,90 30,85 110,78" />
            </Grid>

As shown in above example 2, i have created three polygon one for shade upper part of L shape, one for create L shape and one for shade inner part of L shape.

Example 3 :


          <Grid Grid.Column="2"
                  Margin="10"
                  VerticalAlignment="Center">
                <Grid.Effect>
                    <DropShadowEffect Color="Black"
                                      Direction="5"
                                      ShadowDepth="2"
                                      BlurRadius="5"
                                      Opacity="0.7" />
                </Grid.Effect>
                <Polygon Stroke="Gray"
                         Points="45,0 0,8 0,61 4,65 4,12 49,4 45,0">
                    <Polygon.Fill>
                        <LinearGradientBrush StartPoint="0.7,0"
                                             EndPoint="0.7,0.5">
                            <GradientStop Color="#E2E4E6"
                                          Offset="1" />
                            <GradientStop Color="#AFAFAF" />
                        </LinearGradientBrush>
                    </Polygon.Fill>
                </Polygon>
                <Polygon x:Name="mypolygon"
                         Points="49,4 4,12 4,65 49,54 49,52 49,52"
                         Fill="LightBlue" />
                <Polygon Points="30,4 4,12 4,65 50,50 50,28 30,30">
                    <Polygon.Fill>
                        <RadialGradientBrush GradientOrigin="1,0.5"
                                             RadiusX="1"
                                             RadiusY="1"
                                             Opacity="0.7">
                            <GradientStop Color="Pink"
                                          Offset="0" />
                            <GradientStop Color="Pink"
                                          Offset="0.62" />
                            <GradientStop Color="Transparent"
                                          Offset="0.62" />
                        </RadialGradientBrush>
                    </Polygon.Fill>
                </Polygon>
                <Polygon Fill="#C8B2AB"
                         Points="50,28 30,35 30,30 45,24" />
            </Grid>

Custom shape using Path

Now we can move onto how to create custom shapes using Path and Data property of Path element.

Path class is used to draw Curves and complex shapes. it describes using Geometry object.There are a various types of Geometry objects describes shpaes are LineGeometry, RectangleGeometry, and EllipseGeometry.

Data attribute in path is used to create complex shapes. it has following commands.

Commands

    M :- Move command establishes a start point for the path.The capital M indicates an absolute         location for the new current point. A lowercase m would indicate relative coordinates.

    L :- Line command creates a straight line between the current point and the specified end point.

    H :- Horizontal Line command creates a horizontal line between the current point and the specified x-coordinate.
 
    V :- Vertical Line command creates a vertical line between the current point and the specified y-coordinate.

   C :- Curve command creates a cubic Bezier curve between the current point and the specified end point by using the two specified control points.
            Syntex  : C controlPoint1 controlPoint2 endPoint
  
  A :- Arc command creates an elliptical arc between the current point and the specified end point.
           Syntex : A size(x-radius, y-radius) rotationAngle isLargeArcFlag sweepDirectionFlag   endPoint
           Example : A 10,5 180 0 1 100,0

  Z :- Close command ends the current figure and creates a line that connects the current point to the starting point of the figure.


Example 1 :


                <Path Data="M0,0 150,0 150,150 50,150 70,200 30,150 0,150 0,0z"
                      Fill="DarkBlue" />

Example 2 :

     <Path Fill="BlanchedAlmond"
           Data="M 0,50 C 30,30 30,30 50,0 C 65,30 65,30 100,50 C 68,68 68,68 50,100 C 30,65 30,65 0,50 Z"
           Stroke="Black"
           StrokeThickness="5" />

In above example 2, I have created shape using curve command.
In C 30,30 30,30 50,0 command C indicates curve ; 30,30 indicates first curve point ; 30,30 indicates second curve point and 50,0 indicates endpoint.

Example 3 :


   <Grid Grid.Column="2">
      <Path Data="M88,25 C86,21 78,7 59,1 C59,1 55,0 48,0 C44,0 39,0 34,2                   
             C20,6 13,16 11,18 C11,18 5,26 4,32 C4,32 1,40 0,50 C0,58 0,65 1,73                        
             C1,80 3,86 5,92 C5,92 8,102 10,105 C11,108 18,119 22,124                                     
             C24,125 35,137 44,145 C51,150 62,160 90,172                  
             C118,160 129,150 136,145 C146,137 157,125 158,124 C163,119 169,108.8 170,105                  
             C172,102 175,92 175,92 C177,86 179,80 180,73 C181,65 181,58 180,50                  
             C179,40 176,32 176,32 C175,26 169,18 169,18 C167,16 160,6 146,2                  
             C141,0 136,0 132,0 C125,0 121,1 121,1 C102,7 93,21 92,25                  
             C91,27 91,27 90,27 C90,27 89,28 88,25z"
            Fill="Red"
            Opacity="0.6"
            Stroke="Black"
            StrokeThickness="3" />
   </Grid>
 
 
Example 4 :



   <Path Canvas.Left="15"
         Canvas.Top="50"
         Stroke="Black"
         Data="M0,0 A10,5 180 0 1 100,0 L100,0 L100,100 L50,100 L50,50 L0,50 Z"
         Fill="DarkBlue"
         Opacity="0.8" />

In above example 4, I have created shape using Line command and Arc command.
In  A10,5 180 0 1 100,0 command A indicates Arc; 10,5 indicates X and Y radius; 180 indicates rotation angle ; 0 indicates large arc flag; 1 indicates sweep direction flag and 100,0 indicates end point.


Clip Property


UIElement.Clip Property takes a Geometry type like (LineGeometry, RectangleGeometry, EllipseGeometry etc.) 
Clip Property is used to define the outline of the contents of a UIElement by get/set the Geometry. It display some area of region by setting outline of region.

Example 1 :
 
    <Image Source="/SilverlightApplication1;component/Images/Penguins.jpg"
           Width="300"
           Grid.Column="0"
           Height="300">
           <Image.Clip>
              <EllipseGeometry RadiusX="100"
                               Center="150,100"
                               RadiusY="100" />
           </Image.Clip>
    </Image>

In above example 1, I have used EllipseGeometry to crop image in a circle.

Example 2 :


   <Image Source="/SilverlightApplication1;component/Images/Penguins.jpg"
          Width="300"
          Grid.Column="1"
          Height="300">
          <Image.Clip>
              <RectangleGeometry Rect="60,50,150,100"
                                 RadiusX="20"
                                 RadiusY="20" />
          </Image.Clip>
   </Image>

So, this way you can create shapes using Geometry types or Custom shapes using Path.

In this article I have tried to explained everything about creating and drawing shapes, clipping objects and custom shapes using commands.