c#新手的一些编程帮助(自己再开发中搜索收集)
在C#里字符串取左边N个字符,右边N个字符,从中间取N个字符的函数2008年04月12日 15:36string teststr="sldkjflskdjfsldfjsldjfreretertert";
string leftstr=teststr.SubString(0,10);//从左边开始取10个
string rightstr=teststr.SubString(teststr.length-10,10); //从右边开始取10个
string middstr=teststr.SubString(10,10);//从左边起第11位开始取10个
怎么解决了,在长期的经历中我发现还是有方法可行的,第二种最佳,是昨天做项目的时候发现的:
第一种方法,想修改绑定的数据源之后再绑定,代码如下:
DataTable dt = EmployerSet.Tables["EmployeesTable"];
DataRow dr = dt.NewRow();
dr["FirstName"] = "--选择所有--";
dt.Rows.InsertAt(dr, 0);
this.comboBox1.DataSource = dt;
this.comboBox1.DisplayMember = "FirstName";
方法二:
采用了数据源的管理对象BindingContext,先将当前项的值修改之后再赋予呈现成员
this.comboBox1.DataSource = EmployerSet;
DataRowView rowV = (DataRowView)this.BindingContext[EmployerSet, "EmployeesTable"].Current;
rowV["FirstName"] = "--选择所有--";
this.comboBox1.DisplayMember = "EmployeesTable.FirstName";
你可以测试发现其实 rowV["FirstName"]原本的值就是EmployeesTable.FirstName中的第一个值,只是后来被修改了,接着赋予其呈现成员,
这里之所以修改数据源会成功,我自己的认为是使用到了数据的管理对象,就好像是管理员可以修改一样而别人无法修改!
有两种方法:直接调用 DateTime.Subtract,得到一个TimeSpan
或者直接DateTime.Tricks相减,差值生成一个TimeSpan,如果想直接得到相差的秒数,可以把差值除以1000000
view plaincopy to clipboardprint?
private static void SubDateTime()
{
DateTime dt1 = Convert.ToDateTime("2010-01-11");
DateTime now = DateTime.Now;
TimeSpan t = now.Subtract(dt1);
Console.Write(" days/hour/minute/second: " + t.Days + "/" + t.Hours + "/" + t.Minutes + "/" + t.Seconds);
long diff = dt1.Ticks - now.Ticks;
t = new TimeSpan(diff);
Console.Write(" days/hour/minute/second: " + t.Days + "/" + t.Hours + "/" + t.Minutes + "/" + t.Seconds);
long diff2 = ((t.Days * 24 + t.Hours) * 60 + t.Minutes) * 60 + t.Seconds;
Console.Write(" t/diff/diff2: " + t + "/" + diff + "/" + diff2);
}
private static void SubDateTime()
{
DateTime dt1 = Convert.ToDateTime("2010-01-11");
DateTime now = DateTime.Now;
TimeSpan t = now.Subtract(dt1);
Console.Write(" days/hour/minute/second: " + t.Days + "/" + t.Hours + "/" + t.Minutes + "/" + t.Seconds);
long diff = dt1.Ticks - now.Ticks;
t = new TimeSpan(diff);
Console.Write(" days/hour/minute/second: " + t.Days + "/" + t.Hours + "/" + t.Minutes + "/" + t.Seconds);
long diff2 = ((t.Days * 24 + t.Hours) * 60 + t.Minutes) * 60 + t.Seconds;
Console.Write(" t/diff/diff2: " + t + "/" + diff + "/" + diff2);
}
结果
days/hour/minute/second: 0/13/24/31
days/hour/minute/second: 0/-13/-24/-31
t/diff/diff2: -13:24:31.9482950/-482719482950/-48271
怎样用递归检查menustrip中有多少个ToolStripMenuItem
private void button1_Click(object sender, EventArgs e)
{
foreach (ToolStripMenuItem item in menuStrip1.Items)
{
richTextBox1.Text += item.Name+"\n";
if (item.DropDownItems.Count > 0)
{
GetMenu(item);
}
}
}
void GetMenu(ToolStripMenuItem item)
{
foreach (ToolStripMenuItem i in item.DropDownItems)
{
richTextBox1.Text += i.Name + "\n";
if (i.DropDownItems.Count > 0)
{
GetMenu(i);
}
}
}
首先先看一段MSDN上的示例程序:打印一个树中所有节点名称
private void PrintRecursive(TreeNode treeNode)
2{
3 // Print the node.
4 System.Diagnostics.Debug.WriteLine(treeNode.Text);
5 MessageBox.Show(treeNode.Text);
6 // Print each node recursively.
7 foreach (TreeNode tn in treeNode.Nodes)
8 {
9 PrintRecursive(tn);
10 }
11}
12
13// Call the procedure using the TreeView.
14private void CallRecursive(TreeView treeView)
15{
16 // Print each node recursively.
17 TreeNodeCollection nodes = treeView.Nodes;
18 foreach (TreeNode n in nodes)
19 {
20 PrintRecursive(n);
21 }
22}
然后要说明的是一下TreeView类和TreeNode类之间的关系:TreeView类中有个只读属性是Nodes,它是属于TreeNodeCollection类型的,而对于一个TreeView它的Nodes属性就是返回treeView根结点的集合。
然后就是我的递归遍历查找一个树节点的方法(由于程序需要我是根据树节点的ImageIndex属性查找的):
private TreeNode FindTreeNode(int imageIndex, TreeNode tnParent)
{
if (tnParent == null)
return null;
if (tnParent.ImageIndex == imageIndex)
return tnParent;
TreeNode tnRet = null;
foreach (TreeNode tn in tnParent.Nodes)
{
tnRet = FindTreeNode(imageIndex, tn);
if (tnRet != null)
break;
}
return tnRet;
}
private TreeNode CallFindNode(int imageIndex, TreeView treeView)
{
TreeNodeCollection nodes = treeView.Nodes;
foreach (TreeNode n in nodes)
{
TreeNode temp = FindTreeNode(imageIndex, n);
if (temp != null)
return temp;
}
return null;
}
/// <summary>
/// 这个是一个点击事件,其中改变了选中节点,
/// 改变选中节点的同时就触发了selectedNodeChanged事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void myControlTransactions_AddCustomer(object sender, EventArgs e)
{
TreeNode temp = CallFindNode(3, treeView1);
if (temp != null)
treeView1.SelectedNode = temp;
}
/// <summary>
/// 名称:checkChildFrmExist
/// 功能:打开当前子窗体,并且关闭除当前子窗体处的所有子窗体
/// 编写时间:2009-04-30
/// </summary>
/// <param name="MdiForm">MDI窗体类</param>
/// <param name="ChildForm">子窗体类</param>
public static void checkChildFrmExist(Form MdiForm, Form ChildForm)
{
foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString()) //用子窗体的Name进行判断是否已实例化,如果存在则将他激活
{
tempChildForm.Close();
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
}
/// <summary>
/// 名称:checkChildFrmExist
/// 功能:打开当前子窗体,并且关闭除当前子窗体处的所有子窗体
/// 编写时间:2009-04-30
/// </summary>
/// <param name="MdiForm">MDI窗体类</param>
/// <param name="ChildForm">子窗体类</param>
public static void checkChildFrmExist(Form MdiForm, Form ChildForm)
{
foreach (Form tempChildForm in MdiForm.MdiChildren)
{
tempChildForm.Close();
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
foreach (Form frm in this.MdiChildren) frm.Close();
Form2 f2 = new Form2();
f2.Show();
}
先出现登录窗体后出现主窗体,办法好像很多,介绍一个我自己的方法。
LoginForm:登录窗体,MainForm:主窗体。
1.按F7进入LoginForm的代码中,声明:public static bool flag=false;
2.登录按钮事件中:
private void 登录按钮_Click(object sender, EventArgs e)
{
// 如果正确登录
flag = true;
this.Close();
}
3.在Program.cs中的Main()里写入粗体字代码:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
LoginForm login = new LoginForm();
login.ShowDialog();
if (LoginForm.flag==true)
{
Application.Run(new MainForm());
}
}
http://hi.baidu.com/fagefafa/blog/item/96d4fff4a5d74629bd310951.html
最近想学习一下C#,加入了张波老师的技术交流群。昨天,群里有朋友问如何使得窗体和控件按照计算机分辨率大小来自动调整调整,从而达到视觉上的自适应效果。如你的窗体大小是按照1280*800的分辨率来设置的,当窗体在其他分辨率下最大化显示,控件大小及字体都按照原来的设置显示,窗体中就出现了空白的地方,而且有的控件错位显示,有的甚至跑到屏幕外看不到了。
最后网上找了相关资料,根据朋友 杯(学会放弃) 发过来的源代码 排除错误 终于实现了程序自适应屏幕分辨率和根据窗口大小改变控件自动调整相对位置功能。
首先说一下我理解的实现过程吧:(我初学者希望别误人子弟O(∩_∩)O~)
首先,将Form窗体的autosizemode 属性设置为 GrowOnly , autosize 属性设置为:FALSE ;windowstate : Maximized。
要根据分辨率调整窗口 就应该想法得到分辨率的值,
float X = Screen.PrimaryScreen.Bounds.Width;
float Y = Screen.PrimaryScreen.Bounds.Height;
我们的程序是根据现在的分辨率与我们设计时的分辨率的比例对窗口与控件进行调整;所以我们要记录原先的控件大小和字体大小信息。这里我们使用tag 属性进行记录:我们定义一个setTag() 方法,有时控件中包含其他控件所以使用递归调用。
private void setTag( Control cons)
{
foreach (Control con in cons.Controls)
{
con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top+":" + con.Font.Size;
if (con.Controls.Count > 0)
{
setTag(con);
}
}
}
(若不想改变字体 con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top;就行了!)
接下来我们应该计算出控件相对原先应该变化的比例:
float x = this.Width;
float y = this.Height;
float newx = x/X;
float newy = y/Y ;
做完准备工作我们应该行动了!定义一个setControls(float newx, float newy, Control cons)方法 ,根据原始大小和变化比例计算出新的大小。
private void setControls(float newx, float newy, Control cons)
{
foreach (Control con in cons.Controls)
{
string[] mytag = con.Tag.ToString().Split(':');
float a = Convert.ToSingle(mytag[0]) * newx;
con.Width = (int)a;
a = Convert.ToSingle(mytag[1]) * newy;
con.Height = (int)(a);
a = Convert.ToSingle(mytag[2]) * newx;
con.Left = (int)(a);
a = Convert.ToSingle(mytag[3]) * newy;
con.Top = (int)(a);
Single currentSize = Convert.ToSingle(mytag[4]) * newy*(float )1.4; //因为字体变化太快容易变得太小看不清 加了个1.4做系数 (不太合理)
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
if (con.Controls.Count > 0)
{
setControls(newx, newy, con);
}
}
}
若不改变字体,将:
Single currentSize = Convert.ToSingle(mytag[4]) * newy*(float )1.4; //因为字体变化太快容易变得太小看不清 加了个1.4做系数 (不太合理)
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
去掉就行了!
添加窗口尺寸改变响应代码同时调用setControls(newx, newy, con);方法:
private void NewOrderDashForm_Resize(object sender, EventArgs e)
{
float x = this.Width;
float y = this.Height;
float newx = x/X;
float newy = y /Y ;
setControls(newx, newy, this);
}
最后在Form1_Load中添加代码:
private void Form1_Load(object sender, EventArgs e)
{
this.Resize += new EventHandler(NewOrderDashForm_Resize);
setTag(this);
NewOrderDashForm_Resize(sender, e);
}
在Form窗体中添加如下方法:
private void setTag(Control cons)
{
//MessageBox.Show("setTag");
foreach (Control con in cons.Controls)
{
con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
if (con.Controls.Count > 0) {
//MessageBox.Show("ok");
setTag(con);
}
}
}
//调整每个控件的大小
private void setControls(float newx, float newy, Control cons)
{
foreach (Control con in cons.Controls)
{
//MessageBox.Show(con.Tag.ToString());
string[] mytag = con.Tag.ToString().Split(':');
float a = Convert.ToSingle(mytag[0]) * newx;
con.Width = (int)a;
a = Convert.ToSingle(mytag[1]) * newy;
con.Height = (int)(a);
a = Convert.ToSingle(mytag[2]) * newx;
con.Left = (int)(a);
a = Convert.ToSingle(mytag[3]) * newy;
con.Top = (int)(a);
Single currentSize = Convert.ToSingle(mytag[4]) * newy;
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
if (con.Controls.Count > 0)
{
setControls(newx, newy, con);
}
}
}
//窗体大小自适应
private void NewOrderDashForm_Resize(object sender, EventArgs e)
{
//MessageBox.Show("resize");
// throw new Exception("The method or operation is not implemented.");
float newx = (this.Width) / X;
float newy = this.Height / Y;
setControls(newx, newy, this);
this.Text = this.Width.ToString() + " " + this.Height.ToString();
}
添加Form_load事件,代码如下
//窗体与控件的自适应
this.Resize += new EventHandler(NewOrderDashForm_Resize);
X = this.Width;
Y = this.Height;
setTag(this);
http://wenku.baidu.com/view/bccb5cbfc77da26925c5b009.html
主要功能:
当在TreeView控件中选中父节点时,子节点全部选中;并能根据各子节点的选中状态自动改变父节点的选中状态。
使用方法:
直接在TreeView控件的AfterCheck(object sender, TreeViewEventArgs e)事件中调用TreeViewCheck类的CheckControl(TreeViewEventArgs e)方法并传入参数e即可。
类代码:
程序代码using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace TreeViewCheck
{
/// <summary>
/// 树节点上下文Checked属性控制
/// </summary>
public static class TreeViewCheck
{
/// <summary>
/// 系列节点 Checked 属性控制
/// </summary>
/// <param name="e"></param>
public static void CheckControl(TreeViewEventArgs e)
{
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node != null)
{
CheckParentNode(e.Node, e.Node.Checked);
}
if (e.Node.Nodes.Count > 0)
{
CheckAllChildNodes(e.Node, e.Node.Checked);
}
}
}
#region 私有方法
//改变所有子节点的状态
private static void CheckAllChildNodes(TreeNode pn, bool IsChecked)
{
foreach (TreeNode tn in pn.Nodes)
{
tn.Checked = IsChecked;
if (tn.Nodes.Count > 0)
{
CheckAllChildNodes(tn, IsChecked);
}
}
}
//改变父节点的选中状态
private static void CheckParentNode(TreeNode curNode, bool IsChecked)
{
bool bChecked = true;
if (curNode.Parent != null)
{
foreach (TreeNode node in curNode.Parent.Nodes)
{
if (node.Checked == false)
{
bChecked = false;
break;
}
}
if (bChecked)
{
curNode.Parent.Checked = true;
CheckParentNode(curNode.Parent, true);
}
else
{
curNode.Parent.Checked = false;
CheckParentNode(curNode.Parent, false);
}
}
}
#endregion
}
}
示例代码:
程序代码 //树节点上下文Checked属性控制
private void tv_AfterCheck(object sender, TreeViewEventArgs e)
{
TreeViewCheck.CheckControl(e);
}
1. 设置全部选中或全部选中,设置参数flag(true/false)
private void checkSubNodes(TreeNode treeNode,bool flag)
{
treeNode.Checked = flag;
foreach (TreeNode tn in treeNode.Nodes)
{
PrintRecursive(tn,flag);
}
}
private void CheckTreeview(TreeView treeView,bool flag)
{
TreeNodeCollection nodes = treeView.Nodes;
foreach (TreeNode n in nodes)
{
checkSubNodes(n,flag);
}
}
2.选中状态的改变:只要选中一个子节点,其父节点就是选中的
我的项目里同时在数据区添加了点数据
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action != TreeViewAction.Unknown)
{
CheckAllChildNodes(e.Node, e.Node.Checked);
//选中父节点
bool bol = e.Node.Checked;
if (e.Node.Parent != null)
{
for (int i = 0; i < e.Node.Parent.Nodes.Count; i++)
{
if (e.Node.Parent.Nodes[i].Checked)
bol = true;
}
e.Node.Parent.Checked = bol;
e.Node.Parent.Tag = 1;
}
}
}
//选中子节点
public void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
{
foreach (TreeNode node in treeNode.Nodes)
{
if (nodeChecked)
{
node.Tag = 1;
}
else
{
node.Tag = 0;
}
node.Checked = nodeChecked;
if (node.Nodes.Count > 0)
{
this.CheckAllChildNodes(node, nodeChecked);
}
}
}
3.设置指定的节点为选中状态
private void SelectSubNodes(TreeNode treeNode, string nodeName)
{
if (treeNode.Text.Equals(nodeName))
{
treeNode.Checked = true;
}
foreach (TreeNode tn in treeNode.Nodes)
{
SelectSubNodes(tn, nodeName);
}
}
private void SelectNodes(TreeView treeView, string nodeName)
{
TreeNodeCollection nodes = treeView.Nodes;
foreach (TreeNode n in nodes)
{
SelectSubNodes(n, nodeName);
}
}
调用OCX控件的步骤:
1、在系统中注册该ocx控件,命令:regsvr32.exe 控件位置(加 /u 参数是取消注册)
2、在.net的工具箱中添加该控件,拖到form中去就可以了。
不用工具箱的话,自己手工添加,需要注意一个问题,就是要用Aximp.exe来包装一下ocx控件的类,然后再程序中引用生成的dll就可以了。
aximp [options]{file.dll | file.ocx}
The following command generates MediaPlayer.dll and AxMediaPlayer.dll for the Media Player control msdxm.ocx.
aximp c:\systemroot\system32\msdxm.ocx
ActiveX 控件导入程序将 ActiveX 控件的 COM 类型库中的类型定义转换为 Windows 窗体控件。
Windows 窗体只能承载 Windows 窗体控件,即从 Control 派生的类。Aximp.exe 生成可承载于 Windows 窗体上的 ActiveX 控件的包装类。这使您得以使用可应用于其他 Windows 窗体控件的同一设计时支持和编程方法论。若要承载 ActiveX 控件,必须生成从 AxHost 派生的包装控件。此包装控件包含基础 ActiveX 控件的一个实例。它知道如何与 ActiveX 控件通信,但它显示为 Windows 窗体控件。这个生成的控件承载 ActiveX 控件并将其属性、方法和事件公开为生成控件的属性、方法和事件。
如果不包装一下直接用,会出现 灾难性 错误。上面已经说明了原因。
在项目中引用生成的ax开头的dll,在窗体代码中增加:
声明一个公有的控件对象:
public AxISPICRECLib.AxISPICREC AxISPICREC;
在InitializeComponent()方法内初始化控件:
AxISPICREC = new AxISPICRECLib.AxISPICREC();//必须new对象,否则窗体设计器出问题
((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).BeginInit();//初始化开始
this.Controls.Add(this.AxISPICREC);//添加控件
((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).EndInit();
this.AxISPICREC.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("AxISPICREC.OcxState")));//设计控件状态
如果遇到“正试图在 os 加载程序锁内执行托管代码”这个错误,请设置“调试”--“异常”
"----"Managed Debugging Assistants"中勾掉"LoaderLock" 就可以了。
public delegate void SetTextHandler(string text);
public delegate void SetTextHandler(string text);
private void SetText(string text)
{
if(textBox4.InvokeRequired==true)
{
SetTextHandler set=new SetTextHandler(SetText);//委托的方法参数应和SetText一致
textBox4.Invoke(set,new object[]{text}); //此方法第二参数用于传入方法,代替形参text
}
else
{
textBox4.Text=text;
}
}
Invoke(new EventHandle(TimerAction), source, e);