2013/10/02

[C#] Customize the delimiter of CSV when loading it by using Excel.Workbook.Open() (VBA)

I got an old program which can load a csv file and do something. The customer wants to change the delimiter from comma (,) to others like ";", "|", or "-"... etc. Sounds like an easy job. But no, it's not. The approach that uses on opening the csv file is
using Microsoft.Office;
....
xlsApp = new Excel.ApplicationClass();
xlsWBs = xlsApp.Workbooks;
xlsWB = xlsWBs.Open(TempFileName,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);

2013/07/15

Update app.config settings at runtime

using System.Configuration;

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationCollection appSettings = config.AppSettings.Settings;

appSettings["WorkingMinutes"].Value = numericUpDownWorkingPeriod.Value.ToString();
appSettings["RestMinutes"].Value = numericUpDownRestPeriod.Value.ToString();
appSettings["PhotoPath"].Value = textBoxPhotoPath.Text.Trim();

config.Save();
ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);


Same as above, different style.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationCollection appSettings = config.AppSettings.Settings;

appSettings["key1"].Value = "value1";
appSettings["key2"].Value = "value2";

config.Save();
ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);

LINQ: Ways to have two filters.

string[] source = new string[5] { "12345", "1234", "45678", "6789", "6" };

// Method 1
var result1 = from o in source
where o.Length > 4 && o.StartsWith("1")
select o;
// Method 2
var result2 = from o in source
where (o.Length > 4 & o.StartsWith("1"))
select o;
// Method 3
var result3 = from o in source
where o.Length > 4
where o.StartsWith("1")
select o;
// Method 4
var result4 = source.Where(o => o.Length > 4).Where(o => o.StartsWith("1"));

Different style:
string[] source = new string[5] { "12345""1234""45678""6789""6" };

// Method 1
var result1 = from o in source
              where o.Length > 4 && o.StartsWith("1")
              select o;
// Method 2
var result2 = from o in source
              where (o.Length > 4 & o.StartsWith("1"))
              select o;
// Method 3
var result3 = from o in source
              where o.Length > 4
              where o.StartsWith("1")
              select o;
// Method 4
var result4 = source.Where(o => o.Length > 4).Where(o => o.StartsWith("1"));

2013/05/14

[Download] FxCop 10.0

I don't know why but when I follow the instruction of downloading the FxCop 10.0, I always got the FxCop 1.36 from the C:\Program Files\Microsoft SDKs\Windows\v7.0A\FXCop folder. After a long search, I found that someone kindly share the setup file at here. Thanks to him!

I put a backup copy here. :)

[TextBox, DataGridView, BindingSource] Search as you type

I created my own search as you type feature by using TextBox, DataGridView, and BindingSource. It's very simple to implement. Here is the code:

PS: I already have a TextBox & a DataGridView on the form.

public partial class LookupTable : Form
{
  // This will be the data source of the DataGridView.
  BindingSource oBindingSource = new BindingSource();
  CallerDTO caller = null;
 
  public LookupTable(DataTable sourceData, CallerDTO sourceDTO)
  {
    InitializeComponent();
    caller = sourceDTO;
 
    // Assign the DataTable to our BindingSource object.
    oBindingSource.DataSource = sourceData;
  }
 
  private void LookupTable_Load(object sender, EventArgs e)
  {
    toolTipFind.SetToolTip(textBoxFind, "You can search by Name or by Code.");
 
    // Assign the BindingSource object to the DataGridView.
    dataGridViewResult.DataSource = oBindingSource;
  }
 
  private void textBoxFind_TextChanged(object sender, EventArgs e)
  {
    TextBox oTextBox = sender as TextBox;
 
    // Here is the key of the whole "Search As You Type" function.
    oBindingSource.Filter = "NAME LIKE '%" + oTextBox.Text + "%' OR CODE LIKE '%" + oTextBox.Text + "%'";
  }
 
  private void dataGridViewResult_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
  {
    // Here I need to send back the value that user clicked on.
    caller.StringResult = dataGridViewResult.Rows[e.RowIndex].Cells[1].Value.ToString();
 
    // This is just a public method for me to do something after user clicking.
    caller.CallerLoad();
    this.Close();
  }
}

Result:
video

2013/03/29

Make Oracle Instant Client work

I installed Oracle Instant Client like others did, extract it at a folder, add the folder to path, change the folder's privilege, add some roles to that folder and have fully access... etc. None of them works.

So the ultimate way to make it work that I found is:
copy the following two files to your application folder "oci.dll" & "oraociei11.dll" and it will work. At least it works for me in my case.

PS: The "oraociei11.dll" has around 124MB of size, and this will make your application become a big monster. I hope you will never have to use this way.

2013/03/04

[C#] Dynamically load assembly (dll)

using System.Reflection;
using IterfaceLibrary;
 
IModuleInfo clientForm = null;
Form clientForm2 = null;
string formID = String.Empty;
Assembly newDll = Assembly.LoadFrom("Test.dll");
 
foreach (Type itemType in newDll.GetTypes())
{
  if (itemType.IsClass)
  {
    if (itemType.FullName.Contains("Form"))
    {
      // Assembly有implement Interface
      clientForm = Activator.CreateInstance(itemType) as IModuleInfo;
      MessageBox.Show(clientForm.ModuleName);
      clientForm.ShowForm(this, "From Main");

      // Assembly沒有implement Interface
      clientForm2 = Activator.CreateInstance(itemType) as Form;
      // 呼叫clientForm2裡面的ShowModuleID()方法,該方法回傳formID字串
      formID = itemType.InvokeMember("ShowModuleID", BindingFlags.InvokeMethod, null,
        clientForm2, null) as string;
      MessageBox.Show(formID);
    }
  }
}

2013/01/25

DBF quick query tool

I created a simple tool for querying *.dbf files.

Two ways to query *.dbf:
1.Free table directory (No *.dbc) (OleDb)

Connection string will be like this:
Provider=vfpoledb;Data Source=C:\temp\WLAB32\;Collating Sequence=machine;

2.Database container (.DBC)

Connection string will be like this:
SourceDB=C:\YourPath\YourDbName.DBC;DRIVER={Microsoft Visual FoxPro Driver};SourceType=DBC;Exclusive=No;BackgroundFetch=Yes;Collate=Machine;Null=Yes;Deleted=Yes

You can download this tool from here.
You may need the VFPOLEDB driver (here)

Reference:
Connection strings for Visual FoxPro / FoxPro 2.x

2013/01/15

Allowing only digitals in textbox

private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
  if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar))
    e.Handled = true;
}

Reference: stackoverflow - How do I make a textbox that only accepts numbers?