net 小技巧
MainForm关闭之后保持程序运行
在Windows应用程序中,一般只有一个主程序入口点,而该窗口则为整个应用程序的主窗口。如果在主窗口中打开新窗口,主窗口只能隐藏,而不能关闭。不过,我们可以修改主程序入口点,使主窗口关闭之后程序仍然运行。
将Main改为:
static void Main()
{
(new Form1()).Show();
Application.Run(); // 启动独立的应用程序线程
}
这样Form1中的this.Close()就不会导致应用程序终止运行了,而且不需要Form1时,可以真正Close从而释放一些资源。不过,应用程序的终止就不要在其他地方控制了,比如在Form2的Closed事件中:
private void Form2_Closed(object sender, System.EventArgs e)
{
Application.Exit();
}
在多文档应用程序中,往往需要在内部维护一个当前活动Form的列表,最后一个Form关闭时,再调用Application.Exit。
避免运用Assembly.LoadFrom
假设你想在另一个project中使用其它dll的assembly,如果它在引用列表中,而且assembly中至少有一个公用项(类、枚举等),那么不要用Assembly.LoadFrom,而用Type.Assembly。
例如,在dll(test.dll)中有一个叫做myclass1的公用的类,那么用下面的代码就可以得到该dll的assembly:
// Need include the namespace if without using
Assembly assem = typeof(myclass1).Assembly;
IP与主机名解析
使用System.Net可以实现与Ping命令行类似的IP解析功能,例如将主机名解析为IP或者反过来:
private string GetHostNameByIP(string ipAddress)
{
IPHostEntry hostInfo = Dns.GetHostByAddress(ipAddress);
return hostInfo.HostName;
}
private string GetIPByHostName(string hostName)
{
System.Net.IPHostEntry hostInfo = Dns.GetHostByName(hostName);
return hostInfo.AddressList[0].ToString();
}
ASP.NET中定制出错页面
在ASP.NET中原始的出错页面会暴露部分源代码,由此带来了潜在的安全隐患。ASP.NET允许应用程序出错时显示用户指定的页面,方法是在web.config文件中修改配置信息。
<? xml version="1.0" encoding="UTF-8" ?>
<configuration>
<system.web>
......
<customErrors mode="On" defaultRedirect="ErrorPage.htm" />
......
</system.web>
</configuration>
上面的配置信息明确指定了当应用程序出错的时候显示用户定制的页面ErrorPage.htm。并且因为各个应用程序有自己独立的web.config配置文件,所以应用程序之间不会互相干扰。
其中,mode属性表示是否启用定制的用户页面,它可取三个值,如下所示:
On 启用定制的出错页面
Off 禁用定制的出错页面
RemoteOnly 启用定制的出错页面但仅展示给远程用户
defaultRedirect属性表示用户定制出错页面的文件名。
屏蔽CTRL-V
在WinForm中的TextBox控件没有办法屏蔽CTRL-V的剪贴板粘贴动作,如果需要一个输入框,但是不希望用户粘贴剪贴板的内容,可以改用RichTextBox控件,并且在KeyDown中屏蔽掉CTRL-V键,例子:
private void richTextBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if(e.Control && e.KeyCode==Keys.V)
e.Handled = true;
}
注意日期型变量值的改变
在将日期型变量作为传给后台程序的参数时请注意一个问题:
若client端的时区设置为北京时间,在client端传了一个日期型参数(如:dteRequestDate = nothing), 此时dterequestdate的值是:12:00:00 midnight, January 1, 0001 C.E.
若server端的时区设置为日本,server端接收到的参数dteRequestDate将自动转化为11:00:00 pm, January 1, 0001 C.E,此时若拿dterequestdate参数与checkdate(dim checkdate as datetime = nothing)比较,系统会认为dterequestdate<>checkdate。
判断一个程序是Debug 还是 Release(by 豆腐生活)
在Dotnet环境下,Framework提供了一个DebuggableAttribute 的class,可以通过如下的代码实现对其编译属性的判断。
try
{
Assembly assm = Assembly.LoadFrom(filename);
bool found = assm.GetCustomAttributes(typeof(DebuggableAttribute), false).Length > 0;
buildType = found ? "Debug" : "Release";
}
catch
{
buildType = "<error>";
}
如何让Label的背景透明(小技巧)
问题很简单不是吗,把Label的BackColor设置成Color.Transparent,然后它就成透明了!表面上看是这样的,但实际上是让它的背景与它的Parent控件的背景一样,这样看上去就是透明的了,实际在它的OnPaintBackGround中,还是完成了一样的绘图工作。
而它这个Label在一个图片上时,你会发现它又变得不透明了,它的背景颜色与PictureBox的背景颜色是一样的。
而我只想要一个可以在图片上也透明的Label。用Google找了一下,没什么结果,大多数是把BackColor修改一下的,当然,也有一些高级方法的:
this.SetStyle(ControlStyles.SupportsTransparentBackColor,true);
其结果与设置背景颜色是一样的,在图片上还是不能透明。
于是我想自己重新写一个透明的label,决定从原来的Label派生,在背景透明时,不去画背景,而只画文字。直接重载OnPaint和OnPaintBackground两个函数,结果发现背景变成黑色的了。郁闷!当OnPaintBackground函数什么也不做时,它实际上用默认的黑色给画了背景。其实我想要的就是让主窗口忽略Label的背景,用原来区域上的图形来绘制该控件的背景。但问题是:我没有办法得到主窗口的给定区域的背景。想用Graphics.FromHwnd,结果是在取得Graphic的时候出现运行时错误,更别说取得图片区域了。至于其它方法,没想也不想去想了。
另一个方法,如果只是想在图片上画一些文字,那么为什么不直接从PictureBox下手呢?重载它的OnPaint方法,绘制我们的文字不就行了吗?背景还是保持原来的不动。这个想法还是很不错的,而且代码也简单。最后结果也非常不错。
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace Webb.InstantReplay.PublicControls.UIControls
{
/// <summary>
/// Summary description for TransparentLabel2.
/// </summary>
public class TransparentLabel2 : System.Windows.Forms.PictureBox
{
//Fields
private Point _Location = new Point(0,0);
//Properties
public Point TextLocation
{
get
{
return this._Location;
}
set
{
this._Location = value;
}
}
[Browsable(true)]
new public string Text
{
get{return base.Text;}
set{base.Text = value;}
}
[Browsable(true)]
new public Font Font
{
get{return base.Font;}
set{base.Font = value;}
}
//
public TransparentLabel2()
{
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
SizeF m_size = e.Graphics.MeasureString(this.Text,this.Font);
e.Graphics.DrawString(this.Text,this.Font,Brushes.Black,new RectangleF(this._Location,m_size));
}
}
}