Monday, November 28, 2016

Unexpected character encountered while parsing value: C. Path '', line 0, position 0. (Deserialize JSON string error)

Hi,
A common issue when deserializing a JSON object is to pass the filepath of the JSON file to the Deserialize() method instead of the string content of that file such as the code below.
var obj = JsonConvert.DeserializeObject<Employee>(@"D:\Data\Employee.json")
When calling the Deserialize() method, you need to make sure that the parameter passed is a JSON string value instead of the file path. Use StreamReader class or File.ReadAllText() to get the content of the JSON file.
using (StreamReader reader = new StreamReader(@"D:\Data\Employee.json")) 
{
 string json = reader.ReadToEnd();
 var obj = JsonConvert.DeserializeObject<Employee>(json);
}

Exclude property mapping in Entity Framework Code First Approach

Hi all,
Given a database table such as User with fields Id, UserName and Password that will be mapped to a class using Entity Framework called User with an additional field of ConfirmPassword.
public class User 
{
 public int Id { get; set; }

 public string UserName { get; set; }

 public string Password { get; set; }
 
 public string ConfirmPassword { get; set; }
}
I would like to exclude the ConfirmPassword field from being mapped to the User table. So, after doing some searching, the solution is to decorate the property with [NotMapped] attribute and make sure to reference the DataAnnotations namespace (System.ComponentModel.DataAnnotations.Schema).
using System.ComponentModel.DataAnnotations.Schema;
public class User : IEntity
{
 public int Id { get; set; }

 public string UserName { get; set; }

 public string Password { get; set; }

 [NotMapped] 
 public string ConfirmPassword { get; set; }
}

Thursday, November 24, 2016

Update DataTable values using LINQ

Hello,
Here's how to update DataTable value(s) using Method or Query syntax in LINQ.
C# Code
private void Form1_Load(object sender, EventArgs e)
{
 DataTable dt = new DataTable("tblEntTable");
 dt.Columns.Add("ID", typeof(string));
 dt.Columns.Add("Amount", typeof(decimal));
 dt.Rows.Add(new object[] {"1", 100.51});
 dt.Rows.Add(new object[] {"2", 200.52});
 dt.Rows.Add(new object[] {"3", 500.24});
 dt.Rows.Add(new object[] {"4", 400.31});
 dt.Rows.Add(new object[] {"5", 600.88});
 dt.Rows.Add(new object[] {"6", 700.11});

 //QuerySyntax(dt);
 MethodSyntax(dt);
}

private void QuerySyntax(DataTable dt)
{
 var result = from row in dt.AsEnumerable()
     select new
     {
      ID = row.Field<string>("ID"),
      Amount = 900.23
     };

 DataGridView1.DataSource = result.ToList();
}

private void MethodSyntax(DataTable dt)
{
 Array.ForEach(dt.AsEnumerable().ToArray(), (row)=>{
  row["Amount"] = 800;
 });

 DataGridView1.DataSource = dt;
}
VB.NET
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 Dim dt As New DataTable("tblEntTable")
 dt.Columns.Add("ID", GetType(String))
 dt.Columns.Add("Amount", GetType(Decimal))
 dt.Rows.Add(New Object() {"1", 100.51})
 dt.Rows.Add(New Object() {"2", 200.52})
 dt.Rows.Add(New Object() {"3", 500.24})
 dt.Rows.Add(New Object() {"4", 400.31})
 dt.Rows.Add(New Object() {"5", 600.88})
 dt.Rows.Add(New Object() {"6", 700.11})

 MethodSyntax(dt)
 'QuerySyntax(dt)
End Sub

Sub MethodSyntax(ByVal dt As DataTable)
 Array.ForEach(dt.AsEnumerable().ToArray(), Sub(row) row("Amount") = 900.23)
 DataGridView1.DataSource = dt
End Sub

Sub QuerySyntax(ByVal dt As DataTable)
 Dim result = From row In dt.AsEnumerable()
     Select New With { _
     .ID = row.Field(Of String)("ID"), _
     .Amount = 800
     }

 DataGridView1.DataSource = result.ToList()
End Sub
Output

Wednesday, November 23, 2016

String was not recognized as a valid DateTime (Assign date value with dd-MM-yyyy format to DateTimePicker control)

Good day!
A question was raised on how to assign a date value with format dd-MM-yyyy (05-11-2016) to a DateTimePicker control Text property. Using Convert.ToDateTime() to assign the given value will cause an exception String was not recognized as a valid DateTime. So, a workaround for this is to parse the date value using DateTime.ParseExact() as presented below. The default format of the DateTimePicker control is long.
var dateObj = DateTime.ParseExact("05-11-2016", "dd-MM-yyyy", CultureInfo.InvariantCulture);
DateAttendancePicker.Text = dateObj.ToString();
Make sure that the second parameter of the function is the correct format of the input value.

Monday, November 21, 2016

DataGridView ComboBox Cascade

Good day to all!
Here's an example of how to perform a combobox lookup or cascade using two DataGridViewComboBoxColumns inside a DataGridView control Combo Lookup in DGV. The solution presented is in VB.NET, so I decided to create a C# equivalent for this. In form load event, populate two DataTables for Roles and Employees. Each employee is assigned to a specific role.
private void Form1_Load(object sender, EventArgs e)
{
 DataGridView1.Rows.Add();

 dtRole.Columns.Add("RoleID");
 dtRole.Columns.Add("RoleName");
 dtRole.Rows.Add(1, "Admin");
 dtRole.Rows.Add(2, "Instructor");
 dtRole.Rows.Add(3, "Utility");

 dtEmployee.Columns.Add("RoleID");
 dtEmployee.Columns.Add("EmployeeID");
 dtEmployee.Columns.Add("EmployeeName");
 dtEmployee.Rows.Add(1, 1, "Sam");
 dtEmployee.Rows.Add(1, 2, "Nicole");
 dtEmployee.Rows.Add(2, 3, "Donald");
 dtEmployee.Rows.Add(2, 4, "Brenda");
 dtEmployee.Rows.Add(3, 5, "Jenny");
 dtEmployee.Rows.Add(3, 6, "Michael");

 Role.ValueMember = dtRole.Columns[0].ColumnName;
 Role.ValueType = typeof(string);
 Role.DisplayMember = dtRole.Columns[1].ColumnName;
 Role.DataSource = dtRole;
}
The cascade code is performed in CellValueChanged event of the DataGridView.
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{            
 if (e.RowIndex >= 0 && ((DataGridView)sender).Columns[e.ColumnIndex].GetType() == typeof(DataGridViewComboBoxColumn))
 {
  if (e.ColumnIndex == ((DataGridView)sender).Columns["Role"].Index)
  {
   if (((DataGridView)sender).Rows[e.RowIndex].Cells["Role"].Value != null)
   {
    DataView employeesDV = new DataView(dtEmployee);
    employeesDV.RowFilter = "RoleID = " + ((DataGridViewComboBoxCell)DataGridView1.Rows[e.RowIndex].Cells["Role"]).Value; //DataGridView1.CurrentCell.Value;
    employeesDV.RowStateFilter = DataViewRowState.CurrentRows;

    if (employeesDV.Count > 0)
    {
     DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)DataGridView1.Rows[e.RowIndex].Cells["Employee"];
     cell.ValueMember = "EmployeeID";
     Role.ValueType = typeof(int);
     cell.DisplayMember = "EmployeeName";
     cell.DataSource = employeesDV;
    }
   }
  }
 }           
}
Role Selection Employees under Instructor Role

Saturday, November 19, 2016

DataGridViewComboBoxColumn show Dropdown in single click instead of double click

Hi,
When adding DataGridViewComboBoxColumn control to a DataGridView control, the dropdown shows when you double click instead of single click. The common fix to this is to set the EditMode property to EditOnEnter. Given that you don't want to alter the default settings of the DataGrid control and you want to handle it through code,I found the solution in this website DATAGRIDVIEWCOMBOBOXCOLUMN REQUIRES MULTIPLE CLICKS TO SELECT AN ITEM from a comment made by a developer. However, there's a slight issue in the code provided since a column index returned might have a -1 index and this will cause an Unhandled Exception. The revision made is to add a condition that will check if the ColumnIndex of the DataGridView cell is greater than or equal to 0.
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
 DataGridView grid = (DataGridView)sender;
 if (e.ColumnIndex >= 0)
 {
  if (grid.Columns[e.ColumnIndex].Name == "Role" || grid.Columns[e.ColumnIndex].Name == "Employee")
  {
   grid.BeginEdit(true);
   ((ComboBox)grid.EditingControl).DroppedDown = true;
  } 
 }
}                
That's it. :-)

Tuesday, November 8, 2016

Login to Facebook account using Webbrowser and LINQ

Hi,
Here's how to login to your facebook account using Webbrowser control and LINQ in Windows Forms. The input elements are checked through their attributes like "email" for email fields, "password" for password fields and "submit" for submission control. These codes are inside the DocumentCompleted event.
C# code
WebBrowser1.Document.GetElementsByTagName("input").Cast<HtmlElement>().FirstOrDefault(t => t.GetAttribute("type") == "email").SetAttribute("value", "your email address");
WebBrowser1.Document.GetElementsByTagName("input").Cast<HtmlElement>().FirstOrDefault(t => t.GetAttribute("type") == "password").SetAttribute("value", "your user name");
WebBrowser1.Document.GetElementsByTagName("input").Cast<HtmlElement>().FirstOrDefault(t => t.GetAttribute("type") == "submit").InvokeMember("click");       
VB.NET Code
WebBrowser1.Document.GetElementsByTagName("input").Cast(Of HtmlElement)().FirstOrDefault(Function(t) t.GetAttribute("type") = "email").SetAttribute("value", "your email address")
WebBrowser1.Document.GetElementsByTagName("input").Cast(Of HtmlElement)().FirstOrDefault(Function(t) t.GetAttribute("type") = "password").SetAttribute("value", "your user name")
WebBrowser1.Document.GetElementsByTagName("input").Cast(Of HtmlElement)().FirstOrDefault(Function(t) t.GetAttribute("type") = "submit").InvokeMember("click")

Inline-Block elements not filling up the entire width of container (div) using width percentage

Hello,
I encountered this issue several weeks ago and decided to put the solution here. This pertains to inline-block elements not occupying the entire width of the container. Each element's width is set using percentage instead of pixels. After doing some research, I found a solution here: Display Inline-Block with Widths as Percent with the solution to set the font-size of the container element to 0 and add style box-sizing to border-box. For the child elements, set the default font size.
CSS Code
.container {
            margin: 0 0 1em 0;
            border: 2px solid black;
            padding: 1em;
            font-size: 0; 
            box-sizing: border-box; 
        }

        nav {
            vertical-align: top;
            display: inline-block;
            width: 25%;
            word-wrap: break-word;
            background-color: lightgray;
            font-size: 16px; 
        }

        .column {
            vertical-align: top;
            display: inline-block;
            width: 75%;
            background-color: blueviolet;
            font-size: 16px; 
        }

        section {           
            background-color: orchid;
        }
HTML Code
<div class="container">
 <nav>
  <ul>
   <li><a href="#">Home</a></li>
   <li><a href="#">Solutions</a></li>
   <li><a href="#">Products</a></li>
   <li><a href="#">FAQ</a></li>
   <li><a href="#">About Us</a></li>
   <li><a href="#">Contact Us</a></li>
  </ul>
 </nav>
 <div class="column">
  <section>
   <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
   </p>
  </section>
  <section>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.
   </p>
  </section>
 </div>
</div>
Fiddle inline-block issue

Sunday, November 6, 2016

WPF DataGrid set RowBackground using AlternationCount and DataTriggers

Hi,
There was a question raised on how to set the WPF DataGrid RowBackground with AlternationCount (alternating row colors) and DataTriggers without overriding the Alternation count. The fix is to declare a DataGrid.Style that contains settings for RowBackGround and AlternationCount. And in your DataGrid.RowStyle, define the DataTriggers to highlight RowBackground based on a given Value.
<DataGrid x:Name="dgEmployees" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Height="346" 
                  RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeColumns="False" 
                  CanUserDeleteRows="False" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Visible" 
                  HeadersVisibility="Column" IsReadOnly="True" >
 <DataGrid.Resources>
  <SolidColorBrush x:Key="ConrolLightColorKey" Color="{DynamicResource {x:Static SystemColors.ControlLightColorKey}}"/>
 </DataGrid.Resources>
 <DataGrid.Style>                
  <Style TargetType="{x:Type DataGrid}">
   <Setter Property="RowBackground" Value="{StaticResource ConrolLightColorKey}"/>
   <Setter Property="AlternationCount" Value="2" />
  </Style>
 </DataGrid.Style>
 <DataGrid.RowStyle>
  <Style TargetType="DataGridRow">
   <Style.Triggers>
    <DataTrigger  Binding="{Binding Department}" Value="1">
     <Setter Property="Background" Value="Red"></Setter>
    </DataTrigger>
    <DataTrigger Binding="{Binding Department}" Value="2">
     <Setter Property="Background" Value="Green"></Setter>
    </DataTrigger>
   </Style.Triggers>
  </Style>
 </DataGrid.RowStyle>
 <DataGrid.Columns>
  <DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="50*" />
  <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" Width="120*" />
  <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" Width="120*" />
  <DataGridTextColumn Header="Department" Binding="{Binding Department}" Width="120*" />
 </DataGrid.Columns>
</DataGrid>

Cheers!

Thursday, November 3, 2016

Read SQL Server XML Data Type Column in C#.NET

Hi all,
In this demo, I have dummy XML files saved to an XML column in a table. The files have the same structure of nodes, except that some files have altered price value of 104.95. The is the structure of the dummy XML file.
<catalog>
  <book id="bk101">
    <author>Gambardella, Matthew</author>
    <title>XML Developer's Guide</title>
    <genre>Computer</genre>
    <price>44.95</price>
    <publish_date>2000-10-01</publish_date>
    <description>
      An in-depth look at creating applications
      with XML.
    </description>
  </book>
  <book id="bk102">
    <author>Ralls, Kim</author>
    <title>Midnight Rain</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-12-16</publish_date>
    <description>
      A former architect battles corporate zombies,
      an evil sorceress, and her own childhood to become queen
      of the world.
    </description>
  </book>
  <book id="bk103">
    <author>Corets, Eva</author>
    <title>Maeve Ascendant</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-11-17</publish_date>
    <description>
      After the collapse of a nanotechnology
      society in England, the young survivors lay the
      foundation for a new society.
    </description>
  </book>
  <book id="bk104">
    <author>Corets, Eva</author>
    <title>Oberon's Legacy</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2001-03-10</publish_date>
    <description>
      In post-apocalypse England, the mysterious
      agent known only as Oberon helps to create a new life
      for the inhabitants of London. Sequel to Maeve
      Ascendant.
    </description>
  </book>
  <book id="bk105">
    <author>Corets, Eva</author>
    <title>The Sundered Grail</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2001-09-10</publish_date>
    <description>
      The two daughters of Maeve, half-sisters,
      battle one another for control of England. Sequel to
      Oberon's Legacy.
    </description>
  </book>
  <book id="bk106">
    <author>Randall, Cynthia</author>
    <title>Lover Birds</title>
    <genre>Romance</genre>
    <price>4.95</price>
    <publish_date>2000-09-02</publish_date>
    <description>
      When Carla meets Paul at an ornithology
      conference, tempers fly as feathers get ruffled.
    </description>
  </book>
  <book id="bk107">
    <author>Thurman, Paula</author>
    <title>Splish Splash</title>
    <genre>Romance</genre>
    <price>4.95</price>
    <publish_date>2000-11-02</publish_date>
    <description>
      A deep sea diver finds true love twenty
      thousand leagues beneath the sea.
    </description>
  </book>
  <book id="bk108">
    <author>Knorr, Stefan</author>
    <title>Creepy Crawlies</title>
    <genre>Horror</genre>
    <price>104.95</price>
    <publish_date>2000-12-06</publish_date>
    <description>
      An anthology of horror stories about roaches,
      centipedes, scorpions  and other insects.
    </description>
  </book>
  <book id="bk109">
    <author>Kress, Peter</author>
    <title>Paradox Lost</title>
    <genre>Science Fiction</genre>
    <price>6.95</price>
    <publish_date>2000-11-02</publish_date>
    <description>
      After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems
      of being quantum.
    </description>
  </book>
  <book id="bk110">
    <author>O'Brien, Tim</author>
    <title>Microsoft .NET: The Programming Bible</title>
    <genre>Computer</genre>
    <price>36.95</price>
    <publish_date>2000-12-09</publish_date>
    <description>
      Microsoft's .NET initiative is explored in
      detail in this deep programmer's reference.
    </description>
  </book>
  <book id="bk111">
    <author>O'Brien, Tim</author>
    <title>MSXML3: A Comprehensive Guide</title>
    <genre>Computer</genre>
    <price>36.95</price>
    <publish_date>2000-12-01</publish_date>
    <description>
      The Microsoft MSXML3 parser is covered in
      detail, with attention to XML DOM interfaces, XSLT processing,
      SAX and more.
    </description>
  </book>
  <book id="bk112">
    <author>Galos, Mike</author>
    <title>Visual Studio 7: A Comprehensive Guide</title>
    <genre>Computer</genre>
    <price>49.95</price>
    <publish_date>2001-04-16</publish_date>
    <description>
      Microsoft Visual Studio 7 is explored in depth,
      looking at how Visual Basic, Visual C++, C#, and ASP+ are
      integrated into a comprehensive development
      environment.
    </description>
  </book>
</catalog>
These files are saved in a table with XML column. Such XML files BOM1.xml and BOM3.xml have price value of 104.95. In order to read the XML column using C# code,you can use Cross Apply query in the command text and as a good practice, use SQLParameter when passing data to the query.
private static void ReadXMLColumn()
{            
 double price = 104.95;
 DataTable table = new DataTable();
 using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
 {
  string query = "SET ANSI_NULLS, QUOTED_IDENTIFIER, CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING ON;"
      + " select * from "
      + " (select id, name, pref.value('(text())[1]', 'varchar(max)') as price "
      + " from "
      + " XMLBooks CROSS APPLY "
      + " bookXML.nodes('(/catalog/book/price)') AS bookXML(pref) "
      + " )  as Result where price = @price;";

  SqlCommand command = new SqlCommand(query, con);
  con.Open();
  command.Parameters.Add("@price", SqlDbType.Float).Value = price;
  using (SqlDataAdapter da = new SqlDataAdapter(command))
  {
   da.Fill(table);
   if (table.Rows.Count > 0)
   {
    foreach (DataRow row in table.Rows)
    {
     Console.WriteLine("ID Number {0} of XML File {1} with XML Price value of {2}", 
           row["id"].ToString(), 
           row["name"].ToString(), price);
    }
   }
  }
 }
}
The code above produces the output such as below.