Wednesday, August 10, 2011

Merging tables in C#.Net

Merging two data of two tables that has same schema is easy just copy data from one table to another and done but what if there is some rows that are in both tables? I used below method to merge two tables, this removes duplicates based on the primary key column.

    private static DataTable Merge(DataTable t1, DataTable t2, string primaryKey)
    {
      string key = primaryKey;
      DataTable dataTable = t1.Copy();
      dataTable.PrimaryKey = new DataColumn[1]
      {
        dataTable.Columns[key]
      };
      dataTable.BeginLoadData();
      foreach (DataRow row in t2.Rows)
      {
        if (dataTable.Rows.Find(row[key]) == null)
        {
          dataTable.ImportRow(row);
        }
      }
      dataTable.EndLoadData();
      return dataTable;
    }

  <LinearGradientBrush x:Key="{ComponentResourceKey {x:Type igDP:XamDataGrid},LabelHighlight}" LinearGradientBrush.StartPoint="0,1" LinearGradientBrush.EndPoint="0,.5" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <GradientStop GradientStop.Offset="0" GradientStop.Color="#FF457FE9" />
    <GradientStop GradientStop.Offset="0.25" GradientStop.Color="#CC3C8CBA" />
    <GradientStop GradientStop.Offset="1" GradientStop.Color="#00103475" />
  LinearGradientBrush>
  <SolidColorBrush x:Key="{ComponentResourceKey {x:Type igDP:XamDataGrid},LabelForeground}" SolidColorBrush.Color="#FFFFFFFF" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
  <LinearGradientBrush x:Key="{ComponentResourceKey {x:Type igDP:XamDataGrid},LabelBackground}" LinearGradientBrush.StartPoint="0,0" LinearGradientBrush.EndPoint="0,1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <GradientStop GradientStop.Offset="0" GradientStop.Color="#FF828796" />
    <GradientStop GradientStop.Offset="0.5" GradientStop.Color="#FF424759" />
    <GradientStop GradientStop.Offset="0.5" GradientStop.Color="#FF303342" />
    <GradientStop GradientStop.Offset="1" GradientStop.Color="#FF191925" />
  LinearGradientBrush>

Sunday, July 10, 2011

Find Which Stored Procedures are using a column in SQL Server

Use below query to find out which stored procedures are using a particular column in SQL Server.

SELECT
OBJECT_NAME(id)
FROM syscomments WHERE [text]
LIKE '%ColumnName%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1
GROUP BY OBJECT_NAME(id)

Saturday, April 23, 2011

Full Screen Image Viewer using WPF

I recently created a Full screen image viewer which can be used to see image in full screen, view them in full size and rotate while in full screen mode. This works on Windows7, I have not tested on other OSs.

It can be downloaded from here.
http://www.4shared.com/file/grwH4BH1/FullShot.html

To use this, just save it at any location at you computer. Go to any image you want to see in full screen and set this as default program (as shown below), Now when ever you double click on an image file, It will be opened using this program in full screen.




















Here are Shortcuts to use it:
Esc : Exit
Right Arrow : Next image in same folder
Left Arrow : Previuos  image in same folder
Up Arrow : Rotate Counter-clock wise
Down Arrow : Rotate Clock wise
Z : View image in its full size
X: Fit image back to screen width/height

Please, let me know what you think of it. Cheers!

Passing arguments to WPF application

Recentely I was working on a WPF application that can be used to open a file when the file is double clicked , so I had to pass the file name to the application. Here is how I did it by overridding OnStartup method in App.xaml.cs.

public partial class App : Application
{
   protected override void OnStartup(StartupEventArgs e)
   {
       if (e.Args != null && e.Args.Length > 0)
      {
           this.Properties["InputArgName"] = e.Args[0];
       }
       base.OnStartup(e);
   }
}
 
This can be access anywhere in the application using below code:
if (Application.Current.Properties["InputArgName"] != null)
{
   string fileName = Application.Current.Properties["InputArgName"].ToString();
}

Thursday, April 7, 2011

Loading different versions of same .Net assembly

In my previous post I described how to load assemblies from a sub folder. You may run into a scenario when assemblies in root folder are referring a particular version of assembly while assemblies in subfolder are referring to a different version of same assembly. Assume this assembly (Lets call it SomeAssembly.dll) is placed in root folder and version no of this is 1.0, now if assemblies in subfolder need to refer 2.0 version of this assembly. So put 2.0 version of this assembly in the subfolder and instruct assembly resolve mechanism to load the assemlies from subfolders if it failed to load automatically. Below code shows how to do it:


static void Main(string[] args)
{
   AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   string locFormat = Environment.CurrentDirectory + "\\{0}\\" + args.Name.Split(',')[0] + ".dll";
   foreach (string subPath in AppDomain.CurrentDomain.RelativeSearchPath.Split(';'))
  {
     string filePath = string.Format(locFormat, subPath);
     if (File.Exists(filePath) && AssemblyName.GetAssemblyName(filePath).FullName == args.Name)
     {
        return Assembly.LoadFile(filePath);
     }
   }
 return null; // Failed to load
}

Note that this also applicable when using binding redirect is not a solution and you want different components with in you application to use a different version of a private assembly, you can put each of those different version in to seperate subfolders(as assembly file name is same only one assembly can be put in a single folder). Use above code and add these subfolders into probing path as described here.

Monday, March 28, 2011

Automatically load .Net assemblies from sub-folder

If you need to put a set of assemblies in a sub folder of output directory, you can set that path as private path of the appdomain. Here is a way to do it and also make it configurable so that a new path can be added easily with recompiling.

Add below entry to App.config
<configuration>
  <configSections>
     <section name="AdditionalProbingPaths" type="System.Configuration.SingleTagSectionHandler"></section>
  </configSections>
</configuration>
<AdditionalProbingPaths Path1="FolderPath" Path2="AnotherPath" Path3="BlahBlah" />


Now in your Main Method write below code.
public static void Main(string[] args_)
{
  var section = (Hashtable)System.Configuration.ConfigurationManager.GetSection("AdditionalProbingPaths");
  foreach (string path in section.Values)
  {
     AppDomain.CurrentDomain.AppendPrivatePath(path);
   }
}

Now when any assembly is to be resolved by run time it will also look at these path. Easy!