Thursday, November 28, 2013

ASP.NET Gridview not getting new values in RowUpdating() Event

Assuming in your row updating event, you do some editing in your textbox and then click update button. The event in turn saves your modified records to the database. However, when you tried rebinding the datasource of gridview it seems that you didn't get the newly updated values. The simple trick would be to set the gridview property EnableViewState to false. :)

Get current ID in Task object (C#)

Doing some research on Task (TPL) i wonder if there's a way in retrieving the id of the current task executing. In thread, we can do it like this:
Code:
Thread.CurrentThread.Name; 
The equivalent code in task is shown below:
Code:
int currentTask = Task.CurrentId;  
Greg

Wednesday, November 27, 2013

Pivot or Crosstab SQL Query (REPOST)

Based from Visual Basic Forums, I learned a tip on using Crosstab/Pivot queries. This is presented with SQL Server Execution Plan. It's better to use the concept of the second one compared with the first one.
 SELECT SUM(CASE WHEN DATEDIFF(DAY, upload_package_received_date, GETDATE()) = 0  THEN 1 ELSE 0 END) AS Today,   
           SUM(CASE WHEN DATEDIFF(DAY, upload_package_received_date, GETDATE()) <= 7 THEN 1 ELSE 0 END) AS Last_Week,   
           SUM(CASE WHEN DATEDIFF(DAY, upload_package_received_date, GETDATE()) <= 30 THEN 1 ELSE 0 END) AS [30 Days Ago]  
      FROM temp_uploadpackage  
 SELECT (SELECT COUNT(1) FROM temp_uploadpackage WHERE DATEDIFF(DAY, upload_package_received_date, GETDATE()) = 0)  AS Today,   
     (SELECT COUNT(1) FROM temp_uploadpackage WHERE DATEDIFF(DAY, upload_package_received_date, GETDATE()) <= 7) AS Last_Week,   
     (SELECT COUNT(1) FROM temp_uploadpackage WHERE DATEDIFF(DAY, upload_package_received_date, GETDATE()) <= 30) AS [30 Days Ago]  

Greg

Wednesday, November 20, 2013

Reference System.Web.Mvc in class Library (ASP.NET Mvc)

If your going to add reference to System.Web.Mvc in your class library, simply locate the assembly in Microsoft ASP.NET folder in program files.

Using search in windows explorer in my workstation, the assemblies are located here:
C:\Program Files\Microsoft ASP.NET\ASP.NET MVC (version_number)\Assemblies

Greg

Friday, November 15, 2013

DataGridview current row returns null in SelectionChanged Event

When retrieving selected row cell values in the DataGridview, you might encounter object not set to reference of an instance. It's because the current row has not been initialized. Check first the cell value of the current row if it has cell contents.
Code:
private void dgvAccounts_SelectionChanged(object sender, EventArgs e)  
 {  
   string countryName = string.Empty;  
   if (dgvAccounts.SelectedRows.Count > 0)  
      {  
         if (dgvAccounts.CurrentRow.Cells[1].Value != null)  
      {  
            countryName = dgvAccounts.CurrentRow.Cells[1].Value.ToString();                   
         }        
   }  
 }  
This will ensure that databinding has finished.
Cheers!

Thursday, November 14, 2013

A field or property with the name 'ClassName.Property' was not found on the selected data source (ASP.NET Gridview)

As i was running an asp.net application in my local machine, I encountered an exception which is the title of this post. This asp.net app runs perfectly from the other workstation. I tried searching solutions in google but found out that most of the recommendations were to redo the model or the business tier.

One option I tried was to replace the BoundField of the gridview with TemplateField with label as the bound control using Eval("expression").
Glad that worked. It could be an IIS issue as stated in other forums.
Here's the gridview markup changes:
(Windows 7 64 Bit using BoundField)
 <asp:BoundField DataField="Product.Name" HeaderText="Name" >  
      <ItemStyle Width="350px" />  
 </asp:BoundField>  
(Windows 7 32 Bit using TemplateField)
  <asp:TemplateField HeaderText="Product Name">  
     <ItemStyle Width="350px"/>  
     <ItemTemplate>  
     <asp:Label ID="lblProductName" Text='<%# Eval("Product.Name")%>' runat="server">     
     </asp:Label>  
     </ItemTemplate>                
  </asp:TemplateField>  
Note: I also tested the program in a Windows 8 64 Bit machine. TemplateField simply works. I believe that BoundField has some issues with 32 bit machines.
Cheers!

Using AutoMapper in Asp.Net Database Application

Hello,
Based from Scott Millet's Asp.Net Design Patterns, I was curious on the AutoMapper Framework that maps Domain Entities to View Models. So I tried to give it a spin. Here's the code snippets breakdown:
Order class:
Code:
   /// <summary>  
   /// One order may contain one or many order details.  
   /// </summary>  
   public class Order  
   {  
     public int OrderId { get; set; }  
     public DateTime OrderDate { get; set; }  
     public DateTime RequiredDate { get; set; }  
     public string ShipName { get; set; }  
     public string ShipAddress { get; set; }  
     public IList<OrderDetails> OrderDetail { get; set; }  
   }
Order View class:
Code:
 public class OrderView  
   {  
     public int OrderId { get; set; }  
     public DateTime OrderDate { get; set; }  
     public DateTime RequiredDate { get; set; }  
     public string ShipName { get; set; }  
     public string ShipAddress { get; set; }  
     public IList<OrderDetails> OrderDetail { get; set; }  
   }  
Bootstrapper class:
Code:
//Bootstrapper class  
 public class BootStrapper  
   {  
     public static void ConfigureAutoMapper()  
     {  
       Mapper.CreateMap<Customer, CustomerView>();  
       Mapper.CreateMap<Order, OrderView>();  
       Mapper.CreateMap<OrderDetails, OrderDetailsView>();  
     }  
   }  
Global.asax:
Code:
//Global.asax 
void Application_Start(object sender, EventArgs e) 
{ 
   // Code that runs on application startup       
   BootStrapper.ConfigureAutoMapper(); 
} 
OrderExtension class:
Code:
public static class OrderExtensionMethods  
  {  
    public static OrderView ConvertToOrderView(this Order order)  
    {  
      return Mapper.Map<Order, OrderView>(order);  
    }  
  }  
Order Service class:
Code:
//OrderService class method  
 public CustomerView GetAllOrders(string Id)  
 {  
      CustomerView customerView;  
      ModelCustomer customer = new ModelCustomer();  
      customer.Orders = _orderRepository.FindAllOrders(Id);  
      customerView = customer.ConvertToCustomerView();  
      return customerView;  
 }  
Order Repository class:
Code:
/// <summary>  
     /// Repository class  
     /// Search orders by customer id.  
     /// </summary>  
     public IList<Model.Order> FindAllOrders(string Id)  
     {  
       var Orders = from _order in context.Orders  
              where _order.CustomerID == Id  
              select _order;  
       foreach (var item in Orders)  
           {  
         orders.Add(new ModelOrder()  
         {  
           OrderId = item.OrderID,  
           RequiredDate = Convert.ToDateTime(item.RequiredDate),  
           ShipAddress = item.ShipAddress,  
           ShipName = item.ShipName,  
           OrderDate = Convert.ToDateTime(item.OrderDate),  
           //get details per order  
           OrderDetail = FindAllOrderDetails(item.OrderID)   
         });  
           }  
       return (IList<Model.Order>)orders;  
     }  
Running asp.net website:
As you noticed from the image above, a customer's placed orders
are shown in the first gridview. While the order details of a
specific order is displayed on the second grid.

The asp.net sample focused on the Northwind database.
This application will retrieve all customers and their placed
orders. Additionally, this will retrieve the order details for
a specific order.

Basically, I just derived the concept from Scott's sample and
translatting it to a database project. The changes made for this
application is minimal.

Cheers!

Monday, November 11, 2013

WPF Datagrid Paging in VB.NET using CollectionView class

Based from the solution posted by timmyl here: How can I paginate a WPF DataGrid?. I managed to fix some bugs and added some functionalites such as MoveToFirstPage and MoveToLastPage.

Paging Class
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
Option Infer On  
 Imports System.Collections  
 Imports System.Collections.Generic  
 Imports System.ComponentModel  
 Imports System.Windows.Data  
 
 
 Public Class PageCollectionView  
   Inherits CollectionView  
   Private ReadOnly _innerList As IList  
   Private ReadOnly _itemsPerPage As Integer  
   Private _currentPage As Integer = 1  
   
 
   ' Constructor  
   Public Sub New(ByVal innerList As IList, ByVal itemsPerPage As Integer)  
     MyBase.New(innerList)  
     Me._innerList = innerList  
     Me._itemsPerPage = itemsPerPage  
   End Sub  
   
 
   Public Overrides ReadOnly Property Count() As Integer  
     Get  
       Return Me._itemsPerPage  
     End Get  
   End Property  
   
 
   Public Property CurrentPage() As Integer  
     Get  
       Return _currentPage  
     End Get  
     Set(ByVal value As Integer)  
       _currentPage = value  
       Me.OnPropertyChanged(New PropertyChangedEventArgs("CurrentPage"))  
     End Set  
   End Property
  
  
   Public ReadOnly Property ItemsPerPage() As Integer  
     Get  
       Return Me._itemsPerPage  
     End Get  
   End Property
   
  
   Public ReadOnly Property PageCount() As Integer  
     Get  
       Return (Me._innerList.Count + Me._itemsPerPage - 1) _  
           / Me._itemsPerPage  
     End Get  
   End Property  
   
 
   Private ReadOnly Property EndIndex() As Integer  
     Get  
       Dim _end = Me._currentPage * Me._itemsPerPage - 1  
       Return If(_end > Me._innerList.Count, Me._innerList.Count, _end)  
     End Get  
   End Property
 
  
   Private ReadOnly Property StartIndex() As Integer  
     Get  
       Return (Me._currentPage - 1) * Me._itemsPerPage  
     End Get  
   End Property
 
  
   Public Overrides Function GetItemAt(ByVal index As Integer) As Object  
     Dim offset = index Mod (Me._itemsPerPage)  
     If (((Me.StartIndex + offset) >= Me._innerList.Count)) Then  
       Return New Object  
     Else  
       Dim temp = Me._innerList(Me.StartIndex + offset)  
       Return Me._innerList(Me.StartIndex + offset)  
     End If  
   End Function  
 
 
   Public Sub MoveToFirstPage()  
     If Me._currentPage >= 1 Then  
       Me.CurrentPage = 1  
     End If  
     Me.Refresh()  
   End Sub  
 
 
   Public Sub MoveToPreviousPage()  
     If Me._currentPage > 1 Then  
       Me.CurrentPage -= 1  
     End If  
     Me.Refresh()  
   End Sub  
 
 
   Public Sub MoveToNextPage()  
     If Me._currentPage < Me.PageCount Then  
       Me.CurrentPage += 1  
     End If  
     Me.Refresh()  
   End Sub  
 
 
   Public Sub MoveToLastPage()  
     If Me._currentPage < Me.PageCount Then  
       Me.CurrentPage = Me.PageCount  
     End If  
     Me.Refresh()  
   End Sub  
 End Class

Screenshot:
Note: I didnt include the source code for XAML declaration and the code behind since it can be converted easily.

Greg

Wednesday, November 6, 2013

DataGridview Paging using BindingSource and BindingNavigator in VB.NET

Hi,
In reference to the previous post on DataGridView paging using C# (see link below)
Datagridview paging using BindingSource in C#
I developed a Visual Basic.NET version for your reference:
Main Form Class:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Option Infer On  
      Imports System.Configuration  
      Imports System.ComponentModel  
      Imports MySql  
      Imports MySql.Data  
      Imports MySql.Data.MySqlClient  
      Public Class FBinding  
        Public Property TotalRecords() As Integer  
        Public Const PageSize = 10  
       Private sourceData As New List(Of String)  
       Private dtSource As New DataTable  
       Dim page As New PageOffsetList()  
       Public Sub New()  
         ' This call is required by the designer.  
         InitializeComponent()  
         ' Add any initialization after the InitializeComponent() call.  
         Me.bindingNav.BindingSource = bindingWebsite  
         AddHandler Me.bindingWebsite.CurrentChanged, AddressOf Me.bindingWebsite_CurrentChanged  
         SetSource()  
       End Sub  
       Private Sub FBinding_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
         Me.bindingWebsite.DataSource = page  
       End Sub  
       Private Sub bindingWebsite_CurrentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bindingWebsite.CurrentChanged  
         Dim offset As Integer = CType(Me.bindingWebsite.Current, Int32)  
         Dim records As New List(Of Record)  
         Dim i As Integer = offset  
         While i < offset + PageSize AndAlso i < TotalRecords  
           records.Add(New Record() With  
           { _  
             .Website = sourceData(i).ToString() _  
           })  
           i += 1  
         End While  
         dgWebsites.DataSource = records  
       End Sub  
       Private Sub SetSource()  
         Dim sql As String = "select trim(website_host), url_host from table_website order by trim(website_host) asc"  
         Dim conn As MySqlConnection  
         conn = Nothing  
         Try  
           Dim connection As String = ConfigurationManager.AppSettings("WebsiteConnection").ToString()  
           conn = New MySqlConnection(connection)  
           conn.Open()  
           Dim cmd As New MySqlCommand(sql, conn)  
           Dim da As New MySqlDataAdapter(cmd)  
           da.Fill(dtSource)  
           If dtSource.Rows.Count Then  
             For Each item As DataRow In dtSource.Rows  
               If Not String.IsNullOrEmpty(item(0).ToString()) AndAlso Not String.IsNullOrEmpty(item(1).ToString()) Then  
                 sourceData.Add(item(0).ToString() & ", " & item(1).ToString())  
               End If  
             Next  
           End If  
           TotalRecords = sourceData.Count  
           conn.Close()  
         Catch ex As Exception  
           conn.Close()  
           conn.Dispose()  
         End Try  
       End Sub  
     End Class  

PageOffList Class:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Option Infer On  
 Imports System.ComponentModel  
 Public Class PageOffsetList  
   Implements IListSource  
   Public ReadOnly Property ContainsListCollection() As Boolean _  
     Implements System.ComponentModel.IListSource.ContainsListCollection  
     Get  
       Return False  
     End Get  
   End Property  
   Public Function GetList() As System.Collections.IList _  
     Implements System.ComponentModel.IListSource.GetList  
     Dim pageOffset As New List(Of Int32)  
     Dim offset As Integer = 0  
     While offset <= FBinding.TotalRecords  
       pageOffset.Add(offset)  
       offset = offset + FBinding.PageSize  
     End While  
     Return pageOffset  
   End Function  
 End Class 

Record Class:
1
2
3
Public Class Record  
   Public Property Website As String  
 End Class

Output: Cheers!

DataGridview Paging using BindingSource and BindingNavigator in C#

Here's a simple way to integrate paging in Datagridview using BindingNavigator and BindingSource. The original source can be found here: How can we do paging in datagridview in winform
I made some modifications to simulate loading of thousands of records from a database.
Main Form Class:

Code:
public partial class FBinding : Form  
   {  
     public static int totalRecords { get; set; }  
     public const int pageSize = 10;  
     private List<string> sourceData = new List<string>();  
     private DataTable dtSource = new DataTable();        
     public FBinding()  
     {  
       InitializeComponent();  
       bindingNav.BindingSource = bindingWebsite;  
       bindingWebsite.CurrentChanged += new EventHandler(bindingWebsite_CurrentChanged);  
       SetSource();  
       bindingWebsite.DataSource = new PageOffsetList();  
     }  
     void bindingWebsite_CurrentChanged(object sender, EventArgs e)  
     {  
       // The desired page has changed, so fetch the page of records using the "Current" offset   
       int offset = (int)bindingWebsite.Current;  
       var records = new List<Record>();  
       for (int i = offset; i < offset + pageSize && i < totalRecords; i++)  
       {  
         try  
         {  
           records.Add(new Record() { Website = sourceData[i].ToString() });  
         }  
         catch (Exception ex)  
         {  
         }  
       }  
       dgWebsites.DataSource = records;  
     }  
     private void SetSource()  
     {  
       string sql = string.Format("select trim(website), url from tblwebsite order by trim(website) asc;");  
       MySqlConnection conn = null;  
       try  
       {  
         string connection = ConfigurationManager.AppSettings["AdminWebsite"].ToString();  
         conn = new MySqlConnection(connection);  
         conn.Open();  
         MySqlCommand cmd = new MySqlCommand(sql, conn);  
         MySqlDataAdapter da = new MySqlDataAdapter(cmd);  
         da.Fill(dtSource);  
         if (dtSource.Rows.Count > 0)  
         {  
           //totalRecords = dtSource.Rows.Count;  
           foreach (DataRow item in dtSource.Rows)  
           {  
             if (!string.IsNullOrEmpty(item[0].ToString()) && !string.IsNullOrEmpty(item[1].ToString()))  
             {  
               sourceData.Add(item[0].ToString() + ", " + item[1].ToString());  
             }  
           }  
         }  
         totalRecords = sourceData.Count;  
         conn.Close();  
       }  
       catch (Exception e)  
       {  
         conn.Close();  
         conn.Dispose();  
       }  
     }  
     private void FBinding_Load(object sender, EventArgs e)  
     { }  
   }  
Here's the classes used in Databinding:

Code:
public class Record   
{   
    public string Website { get; set; }   
}   
Paging class:

Code:
public class PageOffsetList : IListSource   
   {   
    public bool ContainsListCollection    
    {    
     get;    
     protected set;   
    }   
    private int TotalRecords = 0;   
    private int pageSize = 0;   
    public PageOffsetList(int pageSize, int total)   
    {   
     this.TotalRecords = total;   
     this.pageSize = pageSize;   
    }   
    public System.Collections.IList GetList()   
    {      
     // Return a list of page offsets based on "totalRecords" and "pageSize"   
     var pageOffsets = new List<int>();   
     for (int offset = 0; offset <= TotalRecords; offset = offset + pageSize)   
     {   
      pageOffsets.Add(offset);   
     }   
     return pageOffsets;   
    }   
   }   
Here's the result of the program:
I also segregated the classes in my application to simplify the approach.
Thanks to the original source! :)

Monday, November 4, 2013

Textbox custom controls with Autosuggest Features (C#)

A textbox custom control developed by Aland Li, MSDN Moderator was the basis for the creation of three new versions of textbox custom controls with Autosuggest features. I managed to fixed some bugs and improve the functionalities of the control.

The first control integrates Suggest + Append feature.
The second control integrates exact keyword searching which is a limitation to the built-in .NET textbox autosuggest feature that is using startswith algorithm.
The third control is an enhancement of the second control
with keyword highlighting,
Thanks to the original creator of the control

Cheers.

Measure width of a given string in pixel (REPOST)

Here's a function to compute the text width of a given string
in pixel. Original Author: Mongus Pong (Stack Overflow)
Code:
protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font, float    
        width, float height )  
      {  
           if ( text == "" )  
                return 0;  
           StringFormat format = new StringFormat ( StringFormat.GenericDefault );  
           RectangleF rect = new RectangleF ( 0, 0, width, 1000 );  
           CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };  
           Region[] regions = new Region[1];  
           format.SetMeasurableCharacterRanges ( ranges );  
           format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;  
           regions = graphics.MeasureCharacterRanges ( text, font, rect, format );  
           rect = regions[0].GetBounds ( graphics );  
           return (int)( rect.Right );  
      }  

Greg