Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

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>

Saturday, April 23, 2011

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!

Type based templating

            <DataTemplate DataType="{x:Type vm:SampleViewModel}">                 <DataTemplate.Resources>       ...