Apply function to LINQ query

•October 24, 2008 • Leave a Comment

In my last project i have been working with linq to do some cool stuff with objects. Like manipulating controls and specially doing any sort of filtering. I gotta say, linq is great for this. Many of you have in some point or another use a for each loop to filter the objects based on their properties; well, this all can be done easier using linq.

Ex. Closing windows using LinQ to object and expressions.  I am filtering all the windows for the current app and at the same time closing them. Calling the Count() function force the linq expression to apply the function and close the window.

private int closeWin(Window w)
{
 w.Close();
 return 0;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{      
 System.Linq.Expressions.Expression<Func<Window, double?>> calc = (w) => closeWin(w);

 var childWindows = (from w in Application.Current.Windows.OfType<Window>()
      where w.Name != “mainWin”
      select calc.Compile().Invoke(w));
 var count = childWindows.Count();
 
}

Xceed single click checkbox

•October 24, 2008 • Leave a Comment

I apologize for not writting sooner,  I was far away from the wpf/silverlight world. Been stuck with a winform project. Thanks God is over.

The latest version of Xceed Datagrid has a lot of goodies. One of the is the single click checkbox.  If we are using a DataGridCollectionView as our dataitem, all we need to do to present the checkbox is declare the itemgrid property of type boolean.

<xceed:DataGridCollectionViewSource x:Key="dgGridSource"
                                         Source="{Binding}">
 <xceed:DataGridCollectionViewSource.ItemProperties>
                <xceed:DataGridItemProperty Name="Name"
    IsReadOnly="True"  ValuePath="Name"    />
                <xceed:DataGridItemProperty Name="Age"
    IsReadOnly="True" ValuePath="Age"   />
                <xceed:DataGridItemProperty Name="Male"
    DataType="{x:Type System:Boolean}"
    IsReadOnly="False" ValuePath="IsMale" />
 </xceed:DataGridCollectionViewSource.ItemProperties>
</xceed:DataGridCollectionViewSource>

 The importan line here is as the DataType attribute. DataType=”{x:Type System:Boolean}”.  In order to have access to the System namespace we need to add this reference to our control. 

 xmlns:System=”clr-namespace:System;assembly=mscorlib”

Then to get the single click editing we need to set the following attributes to the xceed datagrid. EditTrigger and CellEditorDisplayConditions.

<xceed:DataGridControl    x:Name="dgGrid"
                                ItemsSource="{Binding}"
                                EditTriggers="SingleClick"
                                CellEditorDisplayConditions="MouseOverCell"
                               >
</<xceed:DataGridControl>
That's it.  

Transparent WPF Window

•November 29, 2007 • Leave a Comment

 

For those who have played a bit with the exciting WPF windows, you may have noticed that the transparency of the form is related to the the windowstyle property. In other words, if you want to set the AllowTransparecy property to true, you would have to set the WindowStyle property to none.  One may wonder why does MS force us to do this,  well  in short;  Not all of the window is drawn by WPF. The title bar and border are still render by GDI+.  This means that any transformation or rendering possible on all the other objects in WPF are not possible on these two parts of the window. 

Therefore, in order to create a custom transparent window we must get rid of the border drawn by GDI+.  We can accomplish this in one line of code, however we must now handle manually the closing, resizing and dragging.

Xceed Datagrid Custom Cell Styling

•November 22, 2007 • 9 Comments

xceed_customcell1.jpg

As good as Xceed Datagrid is, it’s lacking some basic functionality or the documentation to find the workarounds.  We experience this when we tried to custom change the background of individuals cells base on their value.  A colleague of mine was working on this issue during the last week. After some extensive trial and error he came out with this solution.

Basically we need to register a Xceed.Wpf.DataGridControl.DataRow event,  Any event that gets called for all the DataRows in the DataGrid will suffice.   We decided to use the DataRow.SizeChangedEvent. 

EventManager.RegisterClassHandler(typeof(Xceed.Wpf.DataGrid.DataRow),
Xceed.Wpf.DataGrid.DataRow.SizeChangedEvent, new RoutedEventHandler(onDataRowSizeChanged));

We register a class handler event. This could be done inside the main constructor of your window. After that we implement the handler method as such:


void onDataRowSizeChanged(object sender, RoutedEventArgs e)
{
    Xceed.Wpf.DataGrid.DataRow dRow = (sender as Xceed.Wpf.DataGrid.DataRow);    //Getting the data value of the cells wanted:    DataRowView drView = dRow.DataContext as DataRowView;
    //Do our custom sytling base on data Values
    if (drView["equity"].ToString() == "0")
    {
       dRow.Cells["equity"].Background = Brushes.Red;
    }
    if (drView["balance"].ToString() == "0")
    {
       dRow.Cells["balance"].Background = Brushes.LightGreen;
    }
    if (drView["longvalue"].ToString() == "2282508")
    {
       dRow.Cells["longvalue"].Background = Brushes.Green;
       dRow.Cells["longvalue"].Foreground = Brushes.Blue;
    }
} Below is the xmal of the window: <Window x:Class="WPFPeformanceTest.XceedDataGrid"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"xmlns:xauto="clr-namespace:HelperClasses;assembly=HelperClasses"Title="Xceed DataGrid Custom Cell Style" Height="250" Width="800"WindowStyle="ThreeDBorderWindow"><Grid Name="dataGrid1"><xauto:XceedAutoFitColumnGrid Grid.Row="0" x:Name="accountsGrid" Margin="0,0,0,29" AutoCreateColumns="False"EditTriggers="BeginEditCommand,ActivationGesture" ><xcdg:DataGridControl.Columns><xcdg:Column FieldName="ACCOUNT" ReadOnly="True" Title="account" /><xcdg:Column FieldName="DEPT" ReadOnly="True" Title="dept" /> <xcdg:Column FieldName="longvalue" ReadOnly="True" Title="longvalue"/><xcdg:Column FieldName="balance" Title="balance" /><xcdg:Column FieldName="equity" ReadOnly="True" Title="equity"/><xcdg:Column FieldName="pending" Title="pending" /><xcdg:Column FieldName="reserves" ReadOnly="True" Title="reserves" /></xcdg:DataGridControl.Columns> </xauto:XceedAutoFitColumnGrid> <Label HorizontalAlignment="Left" x:Name="label1" VerticalAlignment="Bottom" Width="201.63" Height="23.2766666666667">Label</Label></Grid></Window>The end result can be viewed at the top of the page.

Autosize Columns XceedDataGrid WPF

•November 8, 2007 • Leave a Comment

Hello Everyone, I know its been a while, but to recent major events in my life i have been caught up.  Either way I am back.  Today I will show you a very useful and practical solution to autosize the columns in the XceedDataGrid fro wpf. 

 There is a property in the columns of the grid that returns the best fitted width of the columns.  Apparently this would be as simple as calling this function and setting the width of the column to the result of the fucntion; however there a couple of issues to consider. Otherwise, the function would return -1.

- The function must be called after the layout of the grid has been updated.  In order to do this we must called it before setting the itemsource of the DataGrid. 

Below there is a implementation of  custom class that inherits from XceedDataGrid and automatically autosized the columns:

public class XceedAutoFitColumnGrid : Xceed.Wpf.DataGrid.DataGridControl
  {
  private bool RunAutoFit = false;
public XceedAutoFitColumnGrid(): base()
  {
this.LayoutUpdated += new EventHandler(Grid_LayoutUpdated);

}
  private void Grid_LayoutUpdated(object sender, EventArgs e)
  {
  if (this.RunAutoFit)
  {
  AutoFit();
  this.RunAutoFit = false;
  }
  }

public void AutoFit()
  {
  foreach (Column col in this.Columns)
  {
  double fittedWidth = col.GetFittedWidth();
  if (fittedWidth > 0) col.Width = fittedWidth + 2;
  }
  }
  protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
  {
  UpdateLayout();
  base.OnItemsSourceChanged(oldValue, newValue);
  if (this.AutoCreateColumns) this.RunAutoFit = true;
  }

}

Generics – List Custom Sorting

•July 20, 2007 • Leave a Comment

Although the concept of templates is not quite new,  the particular implementation of templates done by Generics is quite nice.  I love working with them, they have proven to be very useful and flexible.  If you have not used them before, you should give it a try.

 For this shor example, we will covering one of the useful advantages of the Generic List< >

Custom Sorting
public class Student
{
//For Simplicit purposes these are public
public int age;
public string name;
public string id;

public Student(int _age, string _name, string _id)
{
age = _age;
name = _name;
id = _id;

}

public override string ToString()
{
string s = age + "\n" + name + "\n" + id + "\n";
return s;
}

}

Now we have the class, need to create and instanciate our list of students and add students


//Declare static since this is called from a console application
public static List studentList ;
public static void AddStudents()
{
Student student1 = new Student(20, "Bolton", "M");
Student student2 = new Student(20, "Abel", "M");
Student student3 = new Student(21, "Catherine", "1234");
Student student4 = new Student(21, "Catherine", "1111");
Student student5 = new Student(22, "Bart", "M");

studentList.Add(student1);
studentList.Add(student2);
studentList.Add(student3);

studentList.Add(student4);
studentList.Add(student5);

}

Now lets go unto sorting our list, this is the interesting part.

public static int SortStudents(Student leftStudent, Student rightStudent)
{
//sort first by Age
if (leftStudent.age > rightStudent.age)
return 1;
else if (leftStudent.age < rightStudent.age)
return -1;
else //if both students has the same age
{
//sort by name
if (leftStudent.name.CompareTo(rightStudent.name) != 0)
{
return leftStudent.name.CompareTo(rightStudent.name);
}
else //if both students has the same name and age, sort by id
{
if (leftStudent.id.CompareTo(rightStudent.id) != 0)
{
return leftStudent.id.CompareTo(rightStudent.id);
}
else
{
//in case both students to compare have identical values for all three properties
return 0;
}

}
}
}


The signature of this function is going to be similar for any object we would like to store in our List.
We’ll return an static int, and have will have two parameters of the type we are storing in our List; in this particular example since our list is a List of student we have both parameters of types students. Inside the body of the function we can do any comparison that we want to. Keeping in mind that we always need to return 0 in case both objects have the same value for all their properties. And that is, custom sorting of the objects store in any List.

Below the complete code for our console application example

namespace ListCustomSort
{
class Program
{
public static List studentList ;
static void Main(string[] args)
{
studentList = new List();
AddStudents();
DisplayStudents();

Console.WriteLine("Sorting students");

studentList.Sort(SortStudents);

DisplayStudents();

}

public static void DisplayStudents()
{
foreach(Student student in studentList)
{
Console.Write(student.ToString());
Console.WriteLine("-------------------");
}
}

public static void AddStudents()
{
Student student1 = new Student(20, "Bolton", "M");
Student student2 = new Student(20, "Abel", "M");
Student student3 = new Student(21, "Catherine", "1234");
Student student4 = new Student(21, "Catherine", "1111");
Student student5 = new Student(22, "Bart", "M");

studentList.Add(student1);
studentList.Add(student2);
studentList.Add(student3);
studentList.Add(student4);
studentList.Add(student5);

}

public static int SortStudents(Student leftStudent, Student rightStudent)
{
//sort first by Age
if (leftStudent.age > rightStudent.age)
return 1;
else if (leftStudent.age < rightStudent.age)
return -1;
else //if both students has the same age
{
//sort by name
if (leftStudent.name.CompareTo(rightStudent.name) != 0)
{
return leftStudent.name.CompareTo(rightStudent.name);
}
else //if both students has the same name and age, sort by id
{
if (leftStudent.id.CompareTo(rightStudent.id) != 0)
{
return leftStudent.id.CompareTo(rightStudent.id);
}
else
{
//in case both students to compare have identical values for all three properties
return 0;
}

}

}
}

}
}

Read and Write XML – Isolated Storage

•July 16, 2007 • Leave a Comment

Usually there is certain user related  info we would like to store in other place rather than the database.  For this task, we have several options, storing a a regular file, using the registry to save the settings, and so on.

The .Net framework also gives us the choice to use Isolated Storage,  basically the .Net handles the location of the file and its different for os user and for application.  I won’t go into the details of the Isolated Storage mechanism, but if you would like to have more info visit this link

Msdn Isolated Storage

For this example we would write the info of a DataSet to a xml file using Isolated Storage.
Writting part:
//Get the isolated store for this assembly
isf = IsolatedStorageFile.GetUserStoreForAssembly();
//Create a file at the top level of the store
isfStream = new IsolatedStorageFileStream("DB_Dump.xml", FileMode.OpenOrCreate, FileAccess.Write, isf);

//Create our streamwritter to write content to the file
StreamWriter sw = new StreamWriter(isfStream);

//assign a table to datatable
DataTable dt = ds.Tables[0];

//Write the content of the datatable to my xml file
dt.WriteXml(sw,XmlWriteMode.WriteSchema);

//it is very important to include the XmlWriteMode.WriteSchema,

//otherwise we'll get errors reading the xml file

Now for the reading part:
//Get the isolated store for this assembly
isf = IsolatedStorageFile.GetUserStoreForAssembly();
//Open a file at the top level of the store
isfStream = new IsolatedStorageFileStream("DB_Dump.xml", FileMode.Open, FileAccess.Read, isf);

//Our streamreader to read data
StreamReader sr = new StreamReader(isfStream);

//assign a table to datatable
DataTable dt = new DataTable();

dt.ReadXml(sr.ReadToEnd());

As you can see, its pretty straightforward. The only special consideration is setting the XmlWriteMode to Write Schema.

DataGridView Data Entry Validation

•July 4, 2007 • 5 Comments

I faced this issue a couple of times. How to efectively validate data entry inside a DataGridView.  Well, after doing some research and a bit of trial and error, found out a couple of approaches. 

- Immediate validation:  For those of you who have used dynamic regular expression validator in c#.  This method is pretty similar.  It checks on the fly the data enter by the user.   Msdn has a nice article on how to implemented. 

http://msdn2.microsoft.com/en-us/library/7ehy30d4(VS.80).aspx

- LateValidation: This validation is performed after the user is done entering data.  For the specific project i was working in, it was the perfect choice. However, one has to evaluate the pros and cons of each one.

If you are going to perform complex and multiple validation, you should try the second approach. Also this approach allows the user more flexibility. Lets say the user its not required to enter data in all the rows of the datagridview, the latter approach would work just fine.

On the other hand, if the user is required to enter data in all the rows and the validation is simple; the first approach is convenient.  

In order to implement Immediate validation, the event CellValidation must be handled

Ex

 private void dataGridView1_CellValidating(object sender,
  DataGridViewCellValidatingEventArgs e)
  {
  // Validate the CompanyName entry by disallowing empty strings.
  if (dataGridView1.Columns[e.ColumnIndex].Name == "CompanyName")
  {
  if (String.IsNullOrEmpty(e.FormattedValue.ToString())  &&
  dataGridView1[e.ColumnIndex,e.RowIndex].IsInEditMode )
  {
  dataGridView1.Rows[e.RowIndex].ErrorText =
  "Company Name must not be empty";
       //e.Cancel = true;


  }
  }
  }

The validation to check if the cell is in edit mode is very important. Keep that in mind.

For the Late Validation, there must be an event that is perform once the user finish entering data.  In the implementation of this event,  we would have to go through all the rows that have any info on them and perform the validation required, setting the appropiate error messages in the cell.ErrorMessage property.

 Ex

foreach(DataGridViewRow mRow in datagrid.Rows)
{

if (!Double.TryParse(mRow.Cells["Lots of amount"].FormattedValue.ToString(), out result))

{

mRow.Cells["Lots of amount"].ErrorText = "Please enter a valid number";

//flag to indicate there is an error

error = true;

}

}

Panama .Net UserGroup

•May 28, 2007 • Leave a Comment

Last week I have the opportunity to attend one of the meeting of the .Net Usergroup of Panama.  This group have been around for a couple of years now.  Usually they meet weekly, sometimes every 15 days.  In this group they  cover serveral topics of interest related to the .Net technology.   For instance,  last week they cover a couples of odrm that can be used with .net such as:  n-hibernate and ibatis.  The presentation of this two topics was quite good. The speaker knew his stuff. 

After they cover the basic approach for setting up a WFC  service.  Although the speaker had a clear knowledge of this topic, by rushing through the presentation he was not able to fully explained this interesting topic.   It would have been nice to cover it in more detail.  

In general the presentation was quite nice!!!!

The Code Police: FXCop

•May 8, 2007 • Leave a Comment

One of the common issues programmers face is qa (quality assurance).  Usually this labor involves x amount of resources that focus on testing the application extensively.   As you can imagine, this labor is time consuming and error prone. 

An easy alternative for this issue is FXCOP.

FXCOP is a code analytical tool for .net managed code.  It checks that the code complies to Microsoft .NET Framework Design Guidelines.    It does so, by loading the compiled assembly of the code you want to check.  There is not code test writting involve. Just run FXCOP, open the code assembly you want to check and that’s it.

Usual areas that FXCOP covers include:

  • Library design
  • Localization
  • Naming conventions
  • Performance
  • Security
  • Besides identifying the error or warning we are incurring into, it also give us the exact line of this error and a possible solution for it. While some of this adviced solutions are pretty straight forward, others need a little bit thought to actually implement correctly. 

    By using this tool we can produce secure application of improved quality. 

     Happy Blogging!!!