Pages

Friday, January 27, 2012

C# Event Handler / Delegates

My Notes:

Publishing Events:
Must determine what information to pass to an event within an EventArgs parameter.
Create a custom class that derives from EventArgs.

public class MyEventArgs : EventArgs
{
    public string myName { get; set; }
    public string newName { get; set; }
    public bool cancel { get; set; }
}

A custom class doesn’t have to be created. Any built-in types, which derive from EventArgs can be used, e.g. RoutedEventArgs.
.After creating a custom EventArgs class or using a built-in type deriving from EventArgs, create a public delegate.

Delegates

Delegates are similar to C pointers that reference methods from other classes.

public delegate void NameEventHandler(object sender, EventArgs e);

Above delegate expects to reference methods that return void and passes an object and an EventArgs type. These are considered the signature, and the signature is with any method, which the delegate references.

Examples:

public delegate void BtnClickEventHandler(object sender, RoutedEventArgs e);
 
private delegate bool MyEventHandler(object sender, MyEventArgs e);

  • A delegate is an anonymous function.
  • A delegate’s name can be named anything.
  • Delegates have an invocation list
  • Methods with exact signature can be added to a delegate’s invocation list, which all methods add will be raised.
Events

An event manages delegates and are type safe. Events manages adding and removing of delegates. Only methods added to an invocation list can only be removed by who added it to the list.

Events are Public
public event BtnClickEventHandler BtnClick;
 
public event MyEventHandler My;


Create a Helper Function

Create a method with a signature matching the preferred delegate.

public void OnMy(string name, string newName) 
{
//Reference a new MyEventArgs 
 
MyEventArgs myEvtArgs = new MyEventArgs();
 
myEvtArgs.myName = name;
myEvtArgs.newName = newName;
myEvtArgs.cancel = false;
 
My(this, myEvtArgs);  //Raise the event
 
}




Top to Bottom

private class MyEventArgs : EventArgs
 {
     public string myName { get; set; }
     public string newName { get; set; }
     public bool cancel { get; set; }
 }
 
 private delegate void MyEventHandler(object sender, MyEventArgs e);
 public event MyEventHandler My;
 
 public void OnMy(string name, string newName)
 {
     if (My != null)  //Insure someone is handling the event
     {
         MyEventArgs evtArgs = new MyEventArgs();
         evtArgs.myName = name;
         evtArgs.newName = newName;
         evtArgs.cancel = false;
 
         My(this, evtArgs);
     }
 }
 public MainWindow()
 {
     OnMy("Kirk", "Tom");
 }









Wednesday, January 25, 2012

C# Class Implementation of INotifyPropertyChanged

A simple C# class implementing INotifyPropertyChanged:
INotifyPropertyChanged implements one event:
//Event raised anytime a property on the object changes.
public event PropertyChangedEventHandler PropertyChanged;

which is raised anytime a property on the object is changed.




With the class, include a helper function to handle any change with any object property. It can be name any generic name. When raised, it is passed the proptery name as a string.


//Write a helper function
public void OnPropertyChanged(string propertyName)
{
    //Anyone listening?
    if (PropertyChanged != null)
    {
        //Raise the event
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}


Raise the event in any property within the object.


public double password
{
    get { return _password; }
 
    set
    {
        if (value != _password)
        {
            _password = value;
 
            //Will raise the PropertyChanged event.
            OnPropertyChanged("password");
        }
    }
}

Now, when anytime an object’s property changes, the PropertyChanged will be fired.

Complete code below:


public class Person : INotifyPropertyChanged
{
    private double _password;
    public string username { get; set; }
    public double password
    {
        get { return _password; }
 
        set
        {
            if (value != _password)
            {
                _password = value;
                //Will raise the PropertyChanged event.
                OnPropertyChanged("password");
            }
        }
    }
 
    //Event raised anytime a property on the object changes.
    public event PropertyChangedEventHandler PropertyChanged;
 
    //Write a helper function
    public void OnPropertyChanged(string propertyName)
    {
        //Anyone listening?
        if (PropertyChanged != null)
        {
            //Raise the event
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Friday, January 20, 2012

Working with WPF TreeView Control

With C#, I recursively populated a WPF TreeView control. TreeView control will be populated with a directory listing with their respective files. The code is below:
On Page Load:

XAML:

<TreeView Name="Dir" Height="310">
</TreeView>

Initialize a recursive function call: treeViewItem(DirectoryInfo):

DirectoryInfo dir = new DirectoryInfo(@"C:\Kirk\Images");
Dir.Items.Add(treeViewItem(dir));

Recursive function:
private TreeViewItem treeViewItem(DirectoryInfo dir)
 {
     TreeViewItem tvi = new TreeViewItem();
     tvi.Header = dir.Name;
 
     foreach (DirectoryInfo dirInfo in dir.GetDirectories())
     {
         TreeViewItem t = treeViewItem(dirInfo);
         tvi.Items.Add(t);
     }
 
     IEnumerable<TextBlock> textBlock = dir.GetFiles().Select(f => new TextBlock {Text = f.Name} );
 
     foreach (TextBlock tb in textBlock)
     {
         tvi.Items.Add(tb);
     }
 
     return tvi;
 }

I use lambda expressions on any collection. Lambda expressions are extremely productive and tight.

My coding information.

Friday, October 21, 2011

Google Maps Eight Waypoints Limitation

Google maps DirectionsService (Google Maps API) has a eight waypoint limitation, so I needed to find how to map directions that had more than eight waypoints.

JQuery AJAX call that hit MS SQL Database, which returned a JSON string of waypoints.

Initialized a variable indicating the max waypoints allowed by Google DirectionsService: maxWayPts = 8;

A for loop handled the number of divisions, where an inner loop handled the maximum waypoints. The variable wpLength is the number of waypoints that was returned from the database.

for (var i = 0; i < wpLength; i++) {
    for (var j = i * maxWayPts; j < maxWayPts * (i + 1) - 1; j++)
 
    }
}

Initialized a oBounds object, which has two properties: origin and destination. The origin property holds the first waypoint and destination property holds the last waypoint.

Returned from database: JSON string – Array of objects put into oWayPts variable:



[
{
"title":"Starting Tour at BCT, Berea",
"descrip":"Official Starting Point: Berea Coffee and Tea, Bera KY",
"wayPoints":
[
{
"location":"Berea Coffee and Tea, Berea, KY",
"latLng": {"lat":37.572542,"lng":-84.288762},
"marker":null,
"zDate":"\/Date(1317960000000)\/"
},
{
"location":"Moran Mill Rd, KY",
"latLng":{"lat":37.603667,"lng":-84.347126},
"marker":null,"zDate":"\/Date(1317960000000)\/"
}
]


Initially, origin property is acquired by splicing from the waypoint array (oWayPts). oWayPts is an array of sting objects that was returned from the database.



var oBounds = {};
oBounds.origin = oWayPts.splice(0, 1);

Looping through, waypoints are pushed onto the wayPoints array and its elements are of type google.maps.DirectionsWaypoint. A forced break in the loop when at the end of the waypoints array (oWayPts).


for (var j = i * maxWayPts; j < maxWayPts * (i + 1) - 1; j++) {
    if (typeof oWayPts[j] === "undefined") {
        break;
    } else {
        wayPoints.push(
        {
            location: new google.maps.LatLng(oWayPts[j].latLng.lat, oWayPts[j].latLng.lng),
            stopover: false
        });
    }
}

After the looping through the inner for loop, the oBounds.destination property is set by splicing off the wayPoints array at its end. The oBounds.origin is set to the destination, which causes an overlapping of waypoints.



if (wayPoints.length > 0) {
    oBounds.destination = wayPoints.splice(wayPoints.length - 1, 1);
}

Now, the origin, destination, and waypoints are set. Now it is time to render using google.maps.DirectionsServices,render method, which a google.maps.DirectionsRequest is passed as a parameter. Below is the DirectionsRequest.



var directionsRequest = {
    travelMode: google.maps.DirectionsTravelMode.BICYCLING
}
directionsRequest.origin = new google.maps.LatLng(oBounds.origin[0].latLng.lat, oBounds.origin[0].latLng.lng);
 
/* 
Destination is of type waypoint. A waypoint consists of the following fields: •location (required) specifies the address of the waypoint. • stopover (optional) indicates whether this waypoint is a actual stop on the route (true) or instead only a preference to route through the indicated location (false). Stopovers are true by default.
------------------------------------ */
lat = oBounds.destination[0].location.lat();
lng = oBounds.destination[0].location.lng();
 
directionsRequest.destination = new google.maps.LatLng(lat, lng);
oBounds.origin = [{ latLng: { lat: lat, lng: lng}}];
 
directionsRequest.waypoints = wayPoints;

Now passing in the DirectionsRequest to DirectionsService.render method:


gMap.directionsService.route(directionsRequest, function (result, status) {
     if (status == google.maps.DirectionsStatus.OK) {
         gMap.renderPoints(result);
     }
 });



function renderPoints(arryResult) {
    var directionsRendererOpt = { map: map, suppressMarkers: true };
    var obj = document.getElementById("googleWritten");
    obj.innerHTML = "";
 
        var directionsRenderer = new google.maps.DirectionsRenderer(directionsRendererOpt);
        directionsRenderer.setPanel(obj);
        //Hold on to created overlay, so it could be removed from the map later.
        directionsRenders.push(directionsRenderer);
 
        directionsRenderer.setDirections(arryResult);
}

View a working example at deDogs

Tuesday, October 18, 2011

T-SQL Look-up Table of States and Abbreviations

Creates a table named States and inserts all U.S. states and abbreviations.

 
USE [adminDB]
 
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
CREATE TABLE [dbo].[States](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [state] [nchar](250) NOT NULL,
    [state_abbr] [nchar](5) NOT NULL,
 CONSTRAINT [PK_States] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO
 
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Alabama', N'AL')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Alaska', N'AK')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Arizona', N'AZ')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Arkansas', N'AR')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'California', N'CA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Colorado', N'CO')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Connecticut', N'CT')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Delaware', N'DE')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'District of Columbia', N'DC')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Florida', N'FL')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Georgia', N'GA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Hawaii', N'HI')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Idaho', N'ID')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Illinois', N'IL')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Indiana', N'IN')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Iowa', N'IA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Kansas', N'KS')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Kentucky', N'KY')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Louisiana', N'LA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Maine', N'ME')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Maryland', N'MD')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Massachusetts', N'MA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Michigan', N'MI')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Minnesota', N'MN')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Mississippi', N'MS')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Missouri', N'MO')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Montana', N'MT')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Nebraska', N'NE')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Nevada', N'NV')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'New Hampshire', N'NH')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'New Jersey', N'NJ')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'New Mexico', N'NM')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'New York', N'NY')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'North Carolina', N'NC')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'North Dakota', N'ND')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Ohio', N'OH')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Oklahoma', N'OK')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Oregon', N'OR')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Pennsylvania', N'PA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Rhode Island', N'RI')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'South Carolina', N'SC')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'South Dakota', N'SD')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Tennessee', N'TN')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Texas', N'TX')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Utah', N'UT')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Vermont', N'VT')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Virginia', N'VA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Washington', N'WA')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'West Virginia', N'WV')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Wisconsin', N'WI')
INSERT INTO [adminDB].[dbo].[States]([state],[state_abbr]) VALUES (N'Wyoming', N'WY')
GO