Monday, May 26, 2014

Apply ComboBox Border Color in VB.NET

Here's a simple way to decorate border color in Combobox control. The solution is a conversion of C# code originally developed by a C# Corner forum member.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        AddHandler Me.Paint, AddressOf DrawBorder
    End Sub
 
    Private Sub DrawBorder(ByVal sender As Object, ByVal e As PaintEventArgs)
        Dim rect As New Rectangle(Me.ComboBox1.Location.X - 1,
                                  Me.ComboBox1.Location.Y - 1,
                                  Me.ComboBox1.Width + 1,
                                  Me.ComboBox1.Height + 1)
 
        Dim pen As New Pen(Color.Red, 1)
        Dim g As Graphics = e.Graphics
        g.DrawRectangle(pen, rect)
    End Sub

Customized Combobox

Thursday, May 22, 2014

Cannot assign <null> to anonymous type property (ASP.NET MVC object routeValues)

After reading an article called ASP.NET MVC Partial Rendering by Stewart Leeks, I decided to download the code sample and gave it a spin. As I reviewed each classes and controllers, I needed to implement some changes on saving (ActionResult decorated by [HttpPost]) attribute. The updates would be to pass a value to parameter linkId so that I can add new record after editing a new one.
The first solution I have in mind was to pass a -1 to linkID. This would work but, this will append a -1 to the url being requested.
Code:
return RedirectToAction("ListAndEdit", new { linkId = -1 });
Image:

The second solution was to pass an object to the routeValue. However, this would append a System.Object to the request url.
Code:
return RedirectToAction("ListAndEdit", new { linkId = new object()});
Image
The last solution I cam to think was to pass a null value to the routeValue. Unluckily, you can't assign a null value to an anonymous type property.
Code:
return RedirectToAction("ListAndEdit", new { linkId = null});
After googling for a few hours, I stumbled upon this article: Assigning null to anonymouse type which is the basis for the accepted solution below.
Code:
return RedirectToAction("ListAndEdit", new { linkId = null as object});
Image
As you can see from the image above, there is no parameter value to the requested post url.

Wednesday, May 21, 2014

Validate XML against XSD File (Repost)

In my nature of work, we dealt with XML files and schema on a daily basis. And here's a cool snippet on validating XML file against and XSD file.

C#
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;

public class Form1
{

 private void Form1_Load(SystemObject sender, SystemEventArgs e)
 {
  XmlDocument myDocument = new XmlDocument();
  myDocument.Load("C:\\somefile.xml");
  myDocument.Schemas.Add("namespace here or empty string", "C:\\someschema.xsd");
  ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);
  myDocument.Validate(eventHandler);
 }

 private void ValidationEventHandler(object sender, ValidationEventArgs e)
 {
  switch (e.Severity) {
   case XmlSeverityType.Error:
    Debug.WriteLine("Error: {0}", e.Message);
    break;
   case XmlSeverityType.Warning:
    Debug.WriteLine("Warning {0}", e.Message);
    break;
  }
 }
}

VB.NET
 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
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
 
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim myDocument As New XmlDocument
        myDocument.Load("C:\somefile.xml")
        myDocument.Schemas.Add("namespace here or empty string", "C:\someschema.xsd")
        Dim eventHandler As ValidationEventHandler = New ValidationEventHandler(AddressOf ValidationEventHandler)
        myDocument.Validate(eventHandler)
    End Sub
 
    Private Sub ValidationEventHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
        Select Case e.Severity
            Case XmlSeverityType.Error
                Debug.WriteLine("Error: {0}", e.Message)
            Case XmlSeverityType.Warning
                Debug.WriteLine("Warning {0}", e.Message)
        End Select
    End Sub
 
End Class

Thanks to kleinma(Visual Basic Guru) for this snippet.

Monday, May 19, 2014

Simple Array CRUD manipulation using AngularJS framework

This weekend I decided to create a simple AngularJS CRUD array application. This example was based on Dan Wahlin's AngularJS tutorial. I simply reused the css and js files for simplicity sake. So, let's proceed with the actual scripts and html.

Main HTML (Contains the input controls and div with ng-view directive which is the container of the partial view:
  <div data-ng-controller="CustomerController">  
             <h3>CRUD application in AngularJS Array</h3>  
       <hr />  
       Name:<br />  
             <input id="inName" type="text" data-ng-model="inputData.name" placeholder="name" />  
             <br />  
             City:<br />  
             <input id="inCity" type="text" data-ng-model="inputData.city" placeholder="city" />  
             <br />  
             <button class="btn btn-primary" data-ng-click="saveCustomer()">Save</button>   
       <button class="btn btn-primary" data-ng-click="cancelCustomer()">Cancel</button>        
       <br />  
             <br />  
             Filter by Name:  
             <input id="inSearch" type="text" data-ng-model="nameText" />  
             <br />  
       <div data-ng-view=""></div>      
       <hr />  
        </div>  

Partial View: (Show objects in a table control)
 <table class="tableData">  
   <tr>  
     <th>Name</th>  
     <th>Address</th>  
     <th>Delete</th>  
     <th>Edit</th>  
   </tr>  
   <tr data-ng-repeat="customer in customers | filter:nameText | orderBy:'name'">  
     <td> {{ customer.name }} </td>  
     <td> {{ customer.city }} </td>  
     <td> <button class="btn btn-primary" data-ng-click="removeCustomer(customer)">Delete</button> </td>  
     <td> <button class="btn btn-primary" data-ng-click="editCustomer(customer)">Edit</button> </td>  
   </tr>  
 </table>  

Define Angular Module:
  //'ngRoute' for routing  
 var crudApp = angular.module('crudApp', ['ngRoute']);  
Config Script to handle routes:
  //handle routes here..  
     crudApp.config(function ($routeProvider) {  
       $routeProvider  
         .when('/partial1',  
           {  
             templateUrl: '/AkoDemoPartials/8crudPartial.html',  
             controller: 'CustomerController'  
           })  
         .otherwise({ redirectTo: '/partial1' });  
     });  

Factory script that declares factory object, customer objects and index for the customer in edit mode:
 crudApp.factory('simpleFactory', function () {  
       //create factory object  
       var factory = {};        
       var itemIndex = -1; //index for handling edit  
       var customers = [  
         { name: 'Dave Jones', city: 'Phoenix' },  
         { name: 'Jamie Riley', city: 'Atlanta' },  
         { name: 'Heedy Wahlin', city: 'Chandler' },  
         { name: 'Thomas Winter', city: 'Seattle' }  
       ];  
       //getCustomers is simply going to come in and just return customers.  
       factory.getCustomers = function () {  
         //Can use $http object to retrieve remote data  
         //in a "real" app  
         return customers;  
       };  
       factory.getSelectedIndex = function () {  
         return itemIndex;  
       }  
       return factory;  
     });  

Controller which defines the events such as adding a customer, deleting a customer and editing a customer:
  //pass the factory name  
     crudApp.controller('CustomerController', function ($scope, simpleFactory) {  
       $scope.customers = [];   
       //perform initialization  
       init();  
       function init() {  
         $scope.customers = simpleFactory.getCustomers();  
       }
$scope.saveCustomer = function () { //alert(simpleFactory.itemIndex); if (simpleFactory.itemIndex == -1 || simpleFactory.itemIndex == undefined) { if ($scope.inputData.name != "" && $scope.inputData.name != undefined && $scope.inputData.city != "" && $scope.inputData.name != undefined) { $scope.customers.push( { name: $scope.inputData.name, city: $scope.inputData.city }); } $scope.clearControls(); } else { //perform update on object //alert(simpleFactory.itemIndex + ',' + $scope.customers[simpleFactory.itemIndex].name + ',' + $scope.customers[simpleFactory.itemIndex].city); var customer = $scope.customers[simpleFactory.itemIndex]; customer.name = $scope.inputData.name; customer.city = $scope.inputData.city; $scope.clearControls(); simpleFactory.itemIndex = -1; } }
$scope.removeCustomer = function (item) { var retVal = confirm("Do you want to delete item?"); if (retVal == true) { var index = $scope.customers.indexOf(item) $scope.customers.splice(index, 1); angular.element(document.querySelector('#inSearch')).val(""); angular.element(document.querySelector('#inSearch')).change(); if (index == simpleFactory.itemIndex) { simpleFactory.itemIndex = -1; } } }
$scope.cancelCustomer = function () { $scope.clearControls(); simpleFactory.itemIndex = -1; }
$scope.clearControls = function () { angular.element(document.querySelector('#inName')).val(""); angular.element(document.querySelector('#inCity')).val(""); $scope.triggerChangeEventInputControls(); }
$scope.triggerChangeEventInputControls = function () { angular.element(document.querySelector('#inName')).change(); angular.element(document.querySelector('#inCity')).change(); }
$scope.editCustomer = function (item) { simpleFactory.itemIndex = $scope.customers.indexOf(item); angular.element(document.querySelector('#inName')).val($scope.customers[simpleFactory.itemIndex].name); angular.element(document.querySelector('#inCity')).val($scope.customers[simpleFactory.itemIndex].city); $scope.triggerChangeEventInputControls(); } });

Default UI:

Edit Mode:

Delete Item:

Add Customer:


Cheers!

Wednesday, May 14, 2014

HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory (AngularJS)

Recently interested on AngularJS, I started reading Dan Wahlin's AngularJS material and downloaded the samples in Visual Studio 2012. Upon running the code, I encountered an error which is the title of this post. After days of testing, I noticed that the url doesn't change on runtime since each examples are treated as partial views loaded into a main view. This lead me to the right direction which is a solution from Microsoft on enabling defaultDocument in web.config.

Web.config:
  <system.webServer>  
    <defaultDocument enabled="true">  
      <files>  
       <add value="home.html" />  
      </files>  
    </defaultDocument>  
   </system.webServer>  
Where home.html is the main html document which the partial views are loaded.

Wednesday, May 7, 2014

Register Composite Controls (Custom Controls) in ASP.NET web.config (Repost)

After working on a simple composite control in asp.net, the last task was to register the control so that the asp.net page can consume it. I got it working by registering the control in web.config.

Source:
Register Composite Controls in web.config

Monday, May 5, 2014

Get check status of a CheckedListBox item using text instead of index (Extension Method)

There was a question raised on visual basic forums if you can access an item through it's name rather than index to get it's checked status. My suggestion was to implement a custom control. However, one of the resident MVP in that forum has a better solution using extension method which is simple yet elegant. Below are the extension methods in VB.NET and C#.

VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Module CheckedListBoxExtensions
 
    <Extension()>
    Function GetItemChecked(ByVal source As CheckedListBox, ByVal text As String) As Boolean
        Dim item = source.Items.Cast(Of Object)().FirstOrDefault(Function(o) source.GetItemText(o) = text)
        Dim index = source.Items.IndexOf(item)
        Return source.GetItemChecked(index)
    End Function
 
End Module

C#.NET
Code:
 public static class CheckedListBoxExtensions
    {
        public static bool GetItemChecked(this CheckedListBox source, string text)
        {
            var item = source.Items.Cast<object>().FirstOrDefault(o => source.GetItemText(o) == text);
            var index = source.Items.IndexOf(item);

            return source.GetItemChecked(index);
        }
    }



VB.NET
1
2
3
4
5
6
7
8
9
If (clb.GetItemChecked("US")) Then
            MessageBox.Show("US is checked")
        ElseIf (clb.GetItemChecked("AU")) Then
            MessageBox.Show("AU is checked")
        ElseIf (clb.GetItemChecked("UK")) Then
            MessageBox.Show("UK is checked")
        Else
            MessageBox.Show("None Selected")
        End If

C#
Code:
   if (clb.GetItemChecked("US"))
            {
                MessageBox.Show("US is checked");
            }
            else if (clb.GetItemChecked("AU"))
            {
                MessageBox.Show("AU is checked");
            }
            else if (clb.GetItemChecked("UK"))
            {
                MessageBox.Show("UK is checked");
            }
            else
            {
                MessageBox.Show("None selected");
            }