2018/05/08

Redirect the parent window when inside a frame

One of my project it's website has a frameset setting like the following:
<frameset border="0" frameborder="NO" framespacing="0" rows="110,*">
<frame index="" name="topFrame" noresize="" ome="" scrolling="NO" src="@Url.Action("AgentHeader", "Home")"><frame>
<frame name="main"></frame>
</frameset>

The "main" frame is the major workplace. However, if I set the logout method like the following, only the "main" frame will by redirected to login page. The "topFrame" is still there.
public ActionResult Logout()
{
    .....

    return RedirectToAction("Login", "Home");
}

How to redirect includes the whole page? (The parent window actually)
Here is what I got from the stack overflow and it works for me:
public ActionResult Logout()
{
    .....

    return Content("<html><script>window.top.location.href = 'your url';</script></html>");
}

Please share some other approaches with me if they work in this kind of situation.


Reference: Redirect the entire page from MVC3 Razor iFrame page to a different URL

2015/08/11

Add Tooltip to Html helpers

Use the "title" attribute to the html helper. For example:
@Html.CheckBoxFor(m => m.ForTest, new { title = "測試" })

2015/08/10

Apply Enum onto @Html.DropDownListFor

enum GenderType
{
    male,
    femail,
    others
}
@Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(typeof(GenderType))))

@Html.LabelFor /wo newline

Here is how to prevent @Html.LabelFor from rendering a new line:
@Html.LabelFor(m => m.Title, new { style = "display:inline" })

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:

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?

2012/11/29

Delete a specific DataRow from the DataTable

DataTable dt = BusinessLogic.GetTable(sqlCmd);
dt.Rows.Remove(dt.Select("ColumnName1 = '12345' and ColumnName2 = '67890'")[0]);
dt.AcceptChanges();

2012/11/07

Blog uses new SyntaxHighlighter

I changed to use the latest SyntaxHighlighter recently and found that it causes many posts unreadable. If you found any post that you want to read is unreadable, please leave a message here. I will fix it ASAP.

2012/10/08

WebClient.DownloadString()

I just want to check a web content has something I want or not, so I use the WebClient.DownloadString() instead of using HttpWebRequest, HttpWebResponse, StreamReader... etc.
using (WebClient wclient = new WebClient())
{
    wclient.Encoding = Encoding.UTF8;   // change to fit your environment
    string content = wclient.DownloadString(url);
    result = content.Contains(keyword);
}

2012/08/13

Add parameters in oledb and odbc CommandText

OleDb:
using (OleDbCommand cmd = new OleDbCommand())
{
  cmd.CommandText = "Select * from VIP where ID = ? And RegDate >= ?";
  cmd.Parameters.AddWithValue("id", id);
  cmd.Parameters.AddWithValue("regDate", regDate);
  using (OleDbDataReader reader = cmd.ExecuteReader())
  {
    // ..........
  }
}
Odbc:
using (OdbcCommand cmd = new OdbcCommand())
{
  cmd.CommandText = "Select * from VIP where ID = ? And RegDate >= ?";
  cmd.Parameters.Add("id", OdbcType.Int).Value = id;
  cmd.Parameters.Add("regDate", OdbcType.DateTime).Value = regDate;
  using (OdbcDataReader reader = cmd.ExecuteReader())
  {
    // ..........
  }
}

1. The name of parameter doesn't matter, but the order of parameter does.
2. I didn't include full codes here so don't forget to fill in other components like OleDbConnection or OdbcConnection.

2012/08/06

Trapping F9 in Winform

private void Form2_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.F9)
  {
    // your work here...
  }
}

1. Use the KeyDown event to trap it.
2. Set the Form's KeyPreview property to True.

2012/04/12

Force to show Exception in English

using System.Threading;
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");

Reference: 如何強迫 .Net 應用程式輸出英文的例外訊息

2012/02/16

[C#] Android C2DM

internal static bool sendAndroidNotification(string message, string registrationID)
{
    const String ClientLoginURL = @"https://www.google.com/accounts/ClientLogin";
    const String C2DMServerURL = @"http://android.apis.google.com/c2dm/send";
    string collapseKey = DateTime.Now.ToShortDateString();

    String AuthTokenParams =
        @"accountType=GOOGLE&Email=" + Properties.Settings.Default.AndroidSenderEmail   // your sender email
        + "&Passwd=" + Properties.Settings.Default.AndroidSenderPassword    // your sender password
        + "&service=ac2dm";
    string authToken = getAndroidAuthToken(ClientLoginURL, AuthTokenParams);

    Dictionary<stringstring> data = new Dictionary<stringstring>();
    data.Add("data.msg"HttpUtility.UrlEncode(message));  // use UrlEncode() so that I can push messages other than English (like Chinese)

    return sendAndroidPushMessage(C2DMServerURL, registrationID, collapseKey, authToken, data);
}