一人一块臭豆腐

生活就像一块涂了蜜糖的臭豆腐,刚入口甜甜的,咬下去臭臭的,用心去咀嚼才能体验到香味!

分享按钮

DataGridView二维表头实例

RowMergeView.cs文件内容:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;

    /// <summary>
    /// DataGridView行合并.请对属性MergeColumnNames 赋值既可
    /// </summary>
    public partial class RowMergeView : DataGridView
    {
        #region 构造函数
        public RowMergeView()
        {
            InitializeComponent();

        }
        #endregion
        #region 重写的事件
        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: 在此处添加自定义绘制代码

            // 调用基类 OnPaint
            base.OnPaint(pe);
        }

        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            try
            {
                if (e.RowIndex > -1 && e.ColumnIndex > -1)
                {
                    DrawCell(e);
                }
                else
                {
                    //二维表头
                    if (e.RowIndex == -1)
                    {
                        if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列
                        {
                            //画边框
                            Graphics g = e.Graphics;
                            e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);

                            int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
                            right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;

                            switch (SpanRows[e.ColumnIndex].Position)
                            {
                                case 1:
                                    left += 2;
                                    break;
                                case 2:
                                    break;
                                case 3:
                                    right -= 2;
                                    break;
                            }

                            //画上半部分底色
                            g.FillRectangle(new SolidBrush(this._mergecolumnheaderbackcolor), left, top,
                            right - left, (bottom - top) / 2);

                            //画中线
                            g.DrawLine(new Pen(this.GridColor), left, (top + bottom) / 2,
                            right, (top + bottom) / 2);

                            //写小标题
                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;

                            g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
                            new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), sf);
                            left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;

                            if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width;
                            right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2;
                            if (right < 0) right = this.Width;

                            g.DrawString(SpanRows[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Black,
                            new Rectangle(left, top, right - left, (bottom - top) / 2), sf);
                            e.Handled = true;
                        }
                    }
                }
                base.OnCellPainting(e);
            }
            catch
            { }
        }
        protected override void OnCellClick(DataGridViewCellEventArgs e)
        {
            base.OnCellClick(e);
        }
        #endregion
        #region 自定义方法
        /// <summary>
        /// 画单元格
        /// </summary>
        /// <param name="e"></param>
        private void DrawCell(DataGridViewCellPaintingEventArgs e)
        {
            if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet)
            {
                e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            }
            Brush gridBrush = new SolidBrush(this.GridColor);
            SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor);
            SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
            int cellwidth;
            //上面相同的行数
            int UpRows = 0;
            //下面相同的行数
            int DownRows = 0;
            //总行数
            int count = 0;
            if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1)
            {
                cellwidth = e.CellBounds.Width;
                Pen gridLinePen = new Pen(gridBrush);
                string curValue = e.Value == null ? "" : e.Value.ToString().Trim();
                string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim();
                if (!string.IsNullOrEmpty(curValue))
                {
                    #region 获取下面的行数
                    for (int i = e.RowIndex; i < this.Rows.Count; i++)
                    {
                        if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
                        {
                            //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;

                            DownRows++;
                            if (e.RowIndex != i)
                            {
                                cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    #endregion
                    #region 获取上面的行数
                    for (int i = e.RowIndex; i >= 0; i--)
                    {
                        if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
                        {
                            //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
                            UpRows++;
                            if (e.RowIndex != i)
                            {
                                cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    #endregion
                    count = DownRows + UpRows - 1;
                    if (count < 2)
                    {
                        return;
                    }
                }
                if (this.Rows[e.RowIndex].Selected)
                {
                    backBrush.Color = e.CellStyle.SelectionBackColor;
                    fontBrush.Color = e.CellStyle.SelectionForeColor;
                }
                //以背景色填充
                e.Graphics.FillRectangle(backBrush, e.CellBounds);
                //画字符串
                PaintingFont(e, cellwidth, UpRows, DownRows, count);
                if (DownRows == 1)
                {
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                    count = 0;
                }
                // 画右边线
                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);

                e.Handled = true;
            }
        }
        /// <summary>
        /// 画字符串
        /// </summary>
        /// <param name="e"></param>
        /// <param name="cellwidth"></param>
        /// <param name="UpRows"></param>
        /// <param name="DownRows"></param>
        /// <param name="count"></param>
        private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count)
        {
            SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
            int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;
            int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width;
            int cellheight = e.CellBounds.Height;

            if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
        }
        #endregion
        #region 属性
        /// <summary>
        /// 设置或获取合并列的集合
        /// </summary>
        [MergableProperty(false)]
        [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)]
        [Localizable(true)]
        [Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")]
        public List<string> MergeColumnNames
        {
            get
            {
                return _mergecolumnname;
            }
            set
            {
                _mergecolumnname = value;
            }
        }
        private List<string> _mergecolumnname = new List<string>();
        #endregion
        #region 二维表头
        private struct SpanInfo //表头信息
        {
            public SpanInfo(string Text, int Position, int Left, int Right)
            {
                this.Text = Text;
                this.Position = Position;
                this.Left = Left;
                this.Right = Right;
            }

            public string Text; //列主标题
            public int Position; //位置,1:左,2中,3右
            public int Left; //对应左行
            public int Right; //对应右行
        }
        private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();//需要2维表头的列
        /// <summary>
        /// 合并列
        /// </summary>
        /// <param name="ColIndex">列的索引</param>
        /// <param name="ColCount">需要合并的列数</param>
        /// <param name="Text">合并列后的文本</param>
        public void AddSpanHeader(int ColIndex, int ColCount, string Text)
        {
            if (ColCount < 2)
            {
                throw new Exception("行宽应大于等于2,合并1列无意义。");
            }
            //将这些列加入列表
            int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引
            SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列
            SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列
            for (int i = ColIndex + 1; i < Right; i++) //中间的列
            {
                SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
            }
        }
        /// <summary>
        /// 清除合并的列
        /// </summary>
        public void ClearSpanInfo()
        {
            SpanRows.Clear();
            //ReDrawHead();
        }
        private void DataGridViewEx_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)// && e.Type == ScrollEventType.EndScroll)
            {
                timer1.Enabled = false; timer1.Enabled = true;
            }
        }
        //刷新显示表头
        public void ReDrawHead()
        {
            foreach (int si in SpanRows.Keys)
            {
                this.Invalidate(this.GetCellDisplayRectangle(si, -1, true));
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            ReDrawHead();
        }
        /// <summary>
        /// 二维表头的背景颜色
        /// </summary>
        [Description("二维表头的背景颜色"), Browsable(true), Category("二维表头")]
        public Color MergeColumnHeaderBackColor
        {
            get { return this._mergecolumnheaderbackcolor; }
            set { this._mergecolumnheaderbackcolor = value; }
        }
        private Color _mergecolumnheaderbackcolor = System.Drawing.SystemColors.Control;
        #endregion
    }
使用时调用:
    rowMergeView1.AddSpanHeader(7, 4, "表头标题")
    7为开始列,4为所跨列数。


分享按钮 

从适应到新开始

在辞职2个月后,进入新的公司已经整整11天。在适应整个工作环境之后,我找到了新的开始。

不一样的人,同样的工作,不一样的做事方法,还有正确的态度。让我看到我的未来和希望。

分享按钮

淘宝客网站备案通过,推荐一个免费的空间给大家。

等了快2个月了,前几天才收到备案退回的邮件。

问了下代备案的服务商,说是少了一个文件。

怎么能这样子,不过好在服务商马上补发了文件过去,备案就下来了。

http://www.fasttao.net就是我淘宝客的网站了,用的是店盟淘宝客程序,感觉还是有些问题,现在备案下来也没太多时间去弄,先放着。

朋友们可以进去看下。呵呵

接下来给朋友们推荐的一款空间是德国的com.nu空间,还赠送Mysql空间都足够了。而且有中文,这点确实不错。

想尝试做网站的可以先用用。就是有一点,访问起来有点慢,而且有广告(可以破解去掉)。

另转载破解广告方法:

第一种: 

在页面</body>前加上<noscript> ,在</html>后面也加上<noscript> ,现在结构就变成了: 

<noscript> 
</body>
</html>
<noscript>
如果安装的是WordPress,则可以采用上述方法对主题模版下的footer.php和管理界面的admin-footer.php进行修改。但是最好还是把footer.php、admin-footer.php的属性改为只读(444),以防反弹!

第二种: 

去广告的代码比较简单 只要在尾部加入下列代码即可: 

* <div id=”noAds” > 
<script language=”javascript” type=”text/javascript”>document.getElementById(“noAds”).style.display=”none”;</script>

记住,<div>不要加后面的</div>括号,只要一半就OK了!


分享按钮

面试闲谈

老板永远都希望招聘的员工是全能的…

分享按钮

耒阳,秋风…继续奋斗

秋风,凉意来袭。吹走的不是夏日炎炎而是一腔的创业激情。继续累积创业经验。

分享按钮

耒阳,毛雨

回到家,听着雨点和公鸡打鸣声入眠。感觉真好…

分享按钮

管理经验

森林之王狮子聘请豹子帮他管理10只狼。

在上岗的第一天,狮子就给了豹子一大块肉并让他分给狼。

豹子把肉平均分成了11份,自己拿一份,其他都分给了狼群。大家都相安无事。

在上岗的第二天,狮子又给了豹子一大块肉并让他分给狼,但是很明显肉比昨天的少了。

豹子照旧把肉平均分成11份,自己拿一份,其他都分给了狼群。狼群开始有意见:豹子不用做事情还跟我们吃一样多,这样太不公平了。狼的不满情绪愈演愈烈。

在上岗的第三天,狮子又给了豹子一块肉并让他分给狼,这次肉的分量却只够填饱2只动物的肚子。

豹子照旧把肉平均分成11份,自己拿一份,其他都分给了狼群。狼群看到肉的分量。纷纷向豹子发难。最终在狼群团结一致的情况下。豹子不得不把自己的肉交出来。

第4天,豹子直接向狮子提出辞职。他说10只狼他无法管理。并且向狮子说明了他管理的方式。这个时候狮子又拿出了一块肉,分量和第一天的一样。

狮子把肉分成了11份,并且大小不均,自己拿了一块最大的。其他的抛向狼群。这个时候狼群都在为拿到最大的那块肉战斗。并没有狼提出意见。

豹子很佩服,问狮子这叫什么方法,狮子说“有木有听过人类的绩效工资”

而后狮子又拿出一块和第2天分量一样的肉,分成了10份,同样是大小不均,自己拿了最大的一块。同样狼还是为了自己的那一份食物战斗。最后一条弱小的狼没有分的食物。

豹子很佩服,问狮子这叫什么方法。狮子说“有木有听过末位淘汰法则”

最后狮子又拿出了一块肉,分量和第三天的一样。狮子把肉份成了2份。自己拿一块。其他抛向狼群。最后狼群中最强壮的狼打败了其他所有狼并且吃掉那块肉。

豹子很佩服,问狮子这叫什么方法。狮子说“有木有听过竞争上岗”

 

 

 

 

 

分享按钮

一元之争

人到底有多自私…公共厕所成私人厕所!

分享按钮

辞职,解脱还是失业,打工还是创业。

终于在杂七杂八的工作中解脱出来了。辞职前同事们都叫我先去看下别处的情况,当放2个月长假。但是我实在是忍受不了在这公司工作了。心一横,就是想走。
今天正好辞职一个礼拜。看了下别处的工作,总的来说比之前好了。但是需要跟女朋友2地相隔了。这滋味不怎么好受,年初把女朋友从中山叫过来,说好老老实实做完一年。哪里想实在是超出我的想象了。其实女朋友也没怪我。只是自己心里过意不去。还有就是又需要搬家了。
不搬不知道,一搬才知道4个多月我们买了这么多东西了。整整4趟才完全转移,其中还有一张电视桌送给公司煮饭阿姨了。
搬完东西,整理下心情。正好家里有个朋友酒店开张,回去取下经。看看有没有希望彻底甩掉打工的生活。

未完待续……

分享按钮

地磅程序实例片段[源代码]

最后加的读取ini配置文件功能:
—————————————————————

?View Code CSHARP
        [DllImport("kernel32.dll")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32.dll")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
 
        public static string inifilepath = Application.StartupPath.ToString() + @"\config.ini";//配置文件名称和存放地址
        public static string server = IniReadValue("settings", "databasepath", inifilepath);//数据库连接字符串
        public static int iPort = int.Parse(IniReadValue("settings", "Port", inifilepath));//COM口号
        public static int iRate = int.Parse(IniReadValue("settings", "Rate", inifilepath));//波特率
        public static byte bSize = byte.Parse(IniReadValue("settings", "Size", inifilepath));//数据大小
        public static byte bParity = byte.Parse(IniReadValue("settings", "Parity", inifilepath));//奇偶校验
        public static byte bStopBits = byte.Parse(IniReadValue("settings", "StopBits", inifilepath));//停止位
        public static string BackUpPath = IniReadValue("settings", "backupPath", inifilepath);//数据清理备份存放路径
 
        public static string DATAPATH = IniReadValue("settings", "DATAPath", inifilepath);//数据存放路径
 
        public static void IniWriteValue(string Section, string Key, string Value, string filepath)//对ini文件进行写操作的函数 
        {
            WritePrivateProfileString(Section, Key, Value, filepath);
        }
 
        public static string IniReadValue(string Section, string Key, string filepath)//对ini文件进行读操作的函数 
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(Section, Key, "", temp,
            255, filepath);
            return temp.ToString();
        }     
 
        public int isbl;
 
        public int iTimeout = 1000;
        public string rstr="0";//最后一次正确读数
        public mycom mycom1 = new mycom();
        public byte[] recb;
        public byte[] recb1;

—————————————————————
使用时钟控件检测地磅重量变化
—————————————————————

?View Code CSHARP
        private void timer1_Tick(object sender, EventArgs e)
        {
            textBox12.Text = "";//textBox12用来显示地磅重量
             recb = null;       //存放通过COM口接收的字符串
             mycom1.Close();    //关闭COM连接实例
             mycom1.Open();     //打开COM连接实例
             recb = mycom1.Read(9);//通过COM口接收的字符串,保存9位
             try
             {
                 rstr = Convert.ToString(Convert.ToInt32(aConvert(aToInt(recb))));
                 textBox12.Text = rstr;//把正确输出的重量保存,(在实际使用过程中会出现乱码)
             }
             catch
             {
                 textBox12.Text = rstr;//出现异常情况(出现乱码)的时候,显示最后一次正确的重量!
             }
        }

—————————————————————
把COM口接收的数据连接成数字
aToInt方法

?View Code CSHARP
        public string aToInt(byte[] reb)
        {
            string temp = "";
            for (int i = 1; i <= 8; i++)
            {
                temp += Convert.ToString((char)reb[i]);
            }
            return temp;
        }

—————————————————————
把连接好的数字重新排序
aConvert方法

?View Code CSHARP
        public string aConvert(string rtemp)
        {
            string atemp = "";
            int len = rtemp.Length;
            for (int i = 1; i <= len; i++)
            {
                atemp += rtemp.Substring(len - i, 1);
            }              
            return atemp;
        }

—————————————————————

就这些代码加上一个COMM.Dll接口和kernel32.dll实现 上海耀华xk3190-d2 地磅仪表与计算机的通讯。

分享按钮

【转载】C#调用dll时的类型转换总结

C++(Win 32) C#
char** 作为输入参数转为char[],通过Encoding类对这个string[]进行编码后得到的一个char[]
作为输出参数转为byte[],通过Encoding类对这个byte[]进行解码,得到字符串
C++ Dll接口:

void CplusplusToCsharp(in char** AgentID, out char** AgentIP);

C#中的声明:

[DllImport("Example.dll")]

public static extern void CplusplusToCsharp(char[] AgentID, byte[] AgentIP);

C#中的调用:

Encoding encode = Encoding.Default;

byte[] tAgentID;

byte[] tAgentIP;

string[] AgentIP;

tAgentID = new byte[100];

tAgentIP = new byte[100];

CplusplusToCsharp(encode.GetChars(tAgentID), tAgentIP);

AgentIP[i] = encode.GetString(tAgentIP,i*Length,Length);

Handle IntPtr
Hwnd IntPtr
int* ref int
int& ref int
void* IntPtr
unsigned char* ref byte
BOOL bool
DWORD int 或 uint(int 更常用一些)
枚举类型 Win32:

BOOL MessageBeep(UINT uType // 声音类型); 其中的声音类型为枚举类型中的某一值。

C#:

用户需要自己定义一个枚举类型:

public enum BeepType

{

SimpleBeep = -1,

IconAsterisk = 0×00000040,

IconExclamation = 0×00000030,

IconHand = 0×00000010,

IconQuestion = 0×00000020,

Ok = 0×00000000,

}

C#中导入该函数:

[DllImport("user32.dll")]

public static extern bool MessageBeep(BeepType beepType);

C#中调用该函数:

MessageBeep(BeepType.IconQuestion);

结构类型 Win32:

使用结构指针作为参数的函数:

BOOL GetSystemPowerStatus(

LPSYSTEM_POWER_STATUS lpSystemPowerStatus

);

Win32中该结构体的定义:

typedef struct _SYSTEM_POWER_STATUS {

BYTE  ACLineStatus;

BYTE  BatteryFlag;

BYTE  BatteryLifePercent;

BYTE  Reserved1;

DWORD BatteryLifeTime;

DWORD BatteryFullLifeTime;

} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;

C#:

用户自定义相应的结构体:

struct SystemPowerStatus

{

byte ACLineStatus;

byte batteryFlag;

byte batteryLifePercent;

byte reserved1;

int batteryLifeTime;

int batteryFullLifeTime;

}

C#中导入该函数:

[DllImport("kernel32.dll")]

public static extern bool GetSystemPowerStatus(

ref SystemPowerStatus systemPowerStatus);

C#中调用该函数:

SystemPowerStatus sps;

….sps初始化赋值……

GetSystemPowerStatus(ref sps);

字符串 对于字符串的处理分为以下几种情况:

1、  字符串常量指针的处理(LPCTSTR),也适应于字符串常量的处理,.net中的string类型是不可变的类型。

2、  字符串缓冲区的处理(char*),即对于变长字符串的处理,.net中StringBuilder可用作缓冲区

Win32:

BOOL GetFile(LPCTSTR lpRootPathName);

C#:

函数声明:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

static extern bool GetFile (

[MarshalAs(UnmanagedType.LPTStr)]

string rootPathName);

函数调用:

string pathname;

GetFile(pathname);

备注:

DllImport中的CharSet是为了说明自动地调用该函数相关的Ansi版本或者Unicode版本

 

变长字符串处理:

C#:

函数声明:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

public static extern int GetShortPathName(

[MarshalAs(UnmanagedType.LPTStr)]

string path,

[MarshalAs(UnmanagedType.LPTStr)]

StringBuilder shortPath,

int shortPathLength);

函数调用:

StringBuilder shortPath = new StringBuilder(80);

int result = GetShortPathName(

@”d:\test.jpg”, shortPath, shortPath.Capacity);

string s = shortPath.ToString();

struct 具有内嵌字符数组的结构:

Win32:

typedef struct _TIME_ZONE_INFORMATION {

LONG    Bias;

WCHAR   StandardName[ 32 ];

SYSTEMTIME StandardDate;

LONG    StandardBias;

WCHAR   DaylightName[ 32 ];

SYSTEMTIME DaylightDate;

LONG    DaylightBias;

} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION;

C#:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

struct TimeZoneInformation

{

public int bias;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

public string standardName;

SystemTime standardDate;

public int standardBias;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

public string daylightName;

SystemTime daylightDate;

public int daylightBias;

}

具有回调的函数 Win32:

BOOL EnumDesktops(

HWINSTA hwinsta,       // 窗口实例的句柄

DESKTOPENUMPROC lpEnumFunc, // 回调函数

LPARAM lParam        // 用于回调函数的值

);

回调函数DESKTOPENUMPROC的声明:

BOOL CALLBACK EnumDesktopProc(

LPTSTR lpszDesktop, // 桌面名称

LPARAM lParam    // 用户定义的值

);

C#:

将回调函数的声明转化为委托:

delegate bool EnumDesktopProc(

[MarshalAs(UnmanagedType.LPTStr)]

string desktopName,

int lParam);

该函数在C#中的声明:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool EnumDesktops(
IntPtr windowStation,
EnumDesktopProc callback,
int lParam);

该表对C#中调用win32函数,以及c++编写的dll时参数及返回值的转换做了一个小的总结,如果想进一步了解这方面内容的话,可以参照msdn中“互操作封送处理”一节。

转载于:http://blog.csdn.net/xiaochongchong1248/archive/2010/01/13/5181345.aspx

分享按钮

电话语音查询系统开发

很久之前就说要做一个语音查询系统,无奈客户那边一直没有确认我们的报价.
现在终于确认下来了,也可以开始研究了.
网上找了些资料
客户要求主要是:用户自己打电话查询水费.

客户来电查询
技术要点
其他相关函数介绍请参见实例“语音卡电话呼叫系统”,本实例主要介绍GetCallerIDStr函数,该函数用于获取主叫号码。语法如下:
[DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
public static extern short GetCallerIDStr(short wChnlNo, byte[] IDStr);
参数说明如下。
l wChnlNo:标识通道号。
l IDStr:用于接收读取的号码。
l 返回值:为0,表示未收到任何信息;为1,表示正在接收头信息;为2表示正在接收ID号码;为3表示接收完毕,校验正确;为4表示接收完毕,校验错误。
在调用GetCallerIDStr函数时,只有返回值为3或4才表示已经正确接收了主机号码。
实现过程
(1)新建一个项目,命名为Ex13_12,默认窗体为Form1。
(2)在Form1窗体中,主要添加一个DataGridView控件,显示语音卡各通道和通道状态,并在来电时显示来电号码;添加一个Timer控件用于时刻检测来电信息;添加其他控件及用途如图13.13所示。
(3)主要程序代码。
private void timer1_Tick(object sender, EventArgs e)
{
byte[] ss = new byte[100];
for (short i = 0; i < 8; i++)
{
DJ160API.StartSigCheck(i);
if(open_close==false)
DJ160API.ResetCallerIDBuffer(i);
if (DJ160API.RingDetect(i))
{
open_close = true;
//获取来电号码
result = DJ160API.GetCallerIDStr(i, ss);
if (result == 3 || result == 4)
{
string str = Encoding.UTF8.GetString(ss);
txtTel.Text = str;
txtTel.Text = txtTel.Text.Substring(txtTel.Text.Length - 8, 8);
dataGridView1[2, i].Value = txtTel.Text;
//查询客户资料
this.getMessage(txtTel.Text);
}
}
}
}
private void getMessage(string str)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "db_csell.mdb" + ";Persist Security Info=False");
OleDbDataAdapter dap = new OleDbDataAdapter("SELECT * FROM 个人名录表 WHERE 电话='" + str + "'", con);
DataSet ds = new DataSet();
dap.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
txtName.Text = ds.Tables[0].Rows[0]["姓名"].ToString();
txtDuty.Text = ds.Tables[0].Rows[0]["职务"].ToString();
txtAddress.Text = ds.Tables[0].Rows[0]["地址"].ToString();
txtMobile.Text = ds.Tables[0].Rows[0]["手机"].ToString();
txtCompany.Text = ds.Tables[0].Rows[0]["公司名称"].ToString();
txtPostId.Text = ds.Tables[0].Rows[0]["邮编"].ToString();
}
else
{
labStatus.Text = “非本单位会员客户。。。。”;
}
}
希望有用!
本文代码转载于:http://blog.csdn.net/long102/archive/2007/10/31/1859287.aspx

分享按钮

wordpress Tag中文找不到页面

因为要升级wordpress3.1.1,昨天晚上备份了下数据库,就匆匆的自动升级了.

现在想想觉的有点冲动.要不然想恢复都没办法了.

还好有惊无险,除了网站管理那个模块恢复到从前以外其他都正常.

下午闲着无事到Google看下网站收录情况,针对及个热门的关键字搜索了以下.排名还不错,呵呵!

可是一点进去就转到404页面了.第一反应是不是升级了3.1.1导致的.

因为没升级之前都正常,我有实验过.在Google浏览器正常显示中文都没问题,IE下面转成乱码但是也能访问.

立马BAIDU一下,已经有很多这样的提问了和分享了.随便找了一个

CtuSky:http://www.ctusky.com/archives/chinese-tags-solution-wordpress-error.html

提供了两种解决方法.

一种Win主机(而且必须是使用IIS服务):

1.打开wp-includes/classes.php文件

因为升级到3.1.1之后可能跟之前的版本有点区别,在wp-includes目录下面没有classes.php文件了,而是改成classes-wp.php了.

打开classes-wp.php找到这段代码

if ( isset($_SERVER['PATH_INFO']) )
  $pathinfo = $_SERVER['PATH_INFO'];
else
  $pathinfo = '';
$pathinfo_array = explode('?', $pathinfo);
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
$req_uri = $_SERVER['REQUEST_URI'];
修改成:

if ( isset($_SERVER['PATH_INFO']) )
  $pathinfo = mb_convert_encoding($_SERVER['PATH_INFO'], "UTF-8", "GBK");
else
  $pathinfo = '';
$pathinfo_array = explode('?', $pathinfo);
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
$req_uri = mb_convert_encoding($_SERVER['REQUEST_URI'], "UTF-8", "GBK");

测试已经OK!

 

但是很纳闷为什么之前我都没修改过文件显示标签页面也没有问题.

一种Linux主机:

修改wp-includes/rewrite.php(3.1.1版中这个文件没有变)
这是网上最常见的方法,原理是,让WordPress在对其他内容使用Permalink的时候,对tag不使用,而使用链接2的QueryString模式发送中文编码:

function get_tag_permastruct() {
if (isset($this->tag_structure)) {
return $this->tag_structure;
}
if (empty($this->permalink_structure)) { //-----this line need change------
$this->tag_structure = '';
return false;
}

把第5行改为

if (!empty($this->permalink_structure)) {

局限:没有起到Permalink的“漂亮”作用,如果不能自己修改WP的文件就没办法了。

三、修改tag base
原理同上,只要让WordPress在打开了Permalink功能后继续对tag不理不问就行了。那么,欺骗WordPress,让它用链接2的格式来显示Permalink,可行么?可行,因为WordPress可以自定义Permalink的形式:
在WordPress的 Settings – Permalinks – Tag base 中填上
/?tag=
注意””不能少,引用原文中的写法不对。另外要注意每次输入””,WP都会再次转义为”\”,所以每次点提交都会把””翻一倍,点两次就是”\\”,所以不要多点,一次就对了。
这个方法的结果是使得链接变成这个样子

www.example.com/?tag=/中文/

多出来的斜杠对于服务器丝毫没有影响,还是被视为QueryString,效果同上。
局限是链接变得更加不好看了,更为致命的是插件生成的Sitemap中,tag链接会变成错误的形式,如果你很在乎Sitemap,请不要使用这个方法,除非你真的无法修改自己的rewrite.php文件。

但是当你使用WP-SuperCache或者类似的缓存插件时,它会加入自己的rewrite规则,所有请求先由自己判断,不在缓存中或者不符合缓存规则才交由WordPress处理。但问题在于,它不支持中文URL的解析,哪怕是QueryString也不行。于是我们必须绕过它。
这是WP-SuperCache在.htaccess文件里所添加的rewrite规则

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]

RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]

我们要做的就是不让它去判断中文tag链接,在两个 RewriteCond %{REQUEST_METHOD} !=POST 后面分别加入这样一句:

RewriteCond %{QUERY_STRING} !.*tag=.*

含义是如果QueryString中含有tag字样,请不要解析(交给下一条规则,一般来说就是WordPress的index.php了)。

结论:
Windows+IIS主机下,通过方案一可以完美解决中文tag问题
Linux+Apache主机下,不能使用中文Permalink,除非修改Apache,否则只有用方案二和方案三绕行。
方案二是较为推荐的方法,但是搭配WP-SuperCache使用的时候,需要自己在.htaccess文件中加入一条不处理tag链接的规则。

最后面2个方案没有测试过,如果你的是Linux你可以尝试一下.

 

分享按钮

【转载】C# winform DataGridView 的18种常见属性

C# winform DataGridView 的18种常见属性

C# winform DataGridView 属性说明
① 取得或者修改当前单元格的内容
② 设定单元格只读
③ 不显示最下面的新行
④ 判断新增行
⑤ 行的用户删除操作的自定义
⑥ 行、列的隐藏和删除
⑦ 禁止列或者行的Resize
⑧ 列宽和行高以及列头的高度和行头的宽度的自动调整
⑨ 冻结列或行
⑩ 列顺序的调整
⑪ 行头列头的单元格
⑫ 剪切板的操作
⑬ 单元格的ToolTip的设置
⑭ 右键菜单(ContextMenuStrip)的设置
⑮ 单元格的边框、 网格线样式的设定
⑯ 单元格表示值的设定
⑰ 用户输入时,单元格输入值的设定
⑱ 设定新加行的默认值

——————————————————————————–
① DataGridView 取得或者修改当前单元格的内容:

当前单元格指的是 DataGridView 焦点所在的单元格,它可以通过 DataGridView 对象的 CurrentCell 属性取得。如果当前单元格不存在的时候,返回Nothing(C#是null)

// 取得当前单元格内容
Console.WriteLine(DataGridView1.CurrentCell.Value);
// 取得当前单元格的列 Index
Console.WriteLine(DataGridView1.CurrentCell.ColumnIndex);
// 取得当前单元格的行 Index
Console.WriteLine(DataGridView1.CurrentCell.RowIndex);

另外,使用 DataGridView.CurrentCellAddress 属性(而不是直接访问单元格)来确定单元格所在的
行: DataGridView.CurrentCellAddress.Y
列: DataGridView.CurrentCellAddress.X 。这对于避免取消共享行的共享非常有用。

当前的单元格可以通过设定 DataGridView 对象的 CurrentCell 来改变。可以通过 CurrentCell 来设定
DataGridView 的激活单元格。将 CurrentCell 设为 Nothing(null) 可以取消激活的单元格。
——————————————————————————–

// 设定 (0, 0) 为当前单元格
DataGridView1.CurrentCell = DataGridView1[0, 0];
在整行选中模式开启时,你也可以通过 CurrentCell 来设定选定行。
/// 向下遍历
private void button4_Click(object sender, EventArgs e)
…{
int row = this.dataGridView1.CurrentRow.Index + 1;
if (row > this.dataGridView1.RowCount – 1)
row = 0;
this.dataGridView1.CurrentCell = this.dataGridView1[0, row];
}
/// 向上遍历
private void button5_Click(object sender, EventArgs e)
…{
int row = this.dataGridView1.CurrentRow.Index – 1;
if (row < 0)
row = this.dataGridView1.RowCount – 1;
this.dataGridView1.CurrentCell = this.dataGridView1[0, row];
}
* 注意: this.dataGridView 的索引器的参数是: columnIndex, rowIndex 或是 columnName, rowIndex
这与习惯不同。

——————————————————————————–
② DataGridView 设定单元格只读:

1) 使用 ReadOnly 属性
如果希望,DataGridView 内所有单元格都不可编辑, 那么只要:

// 设置 DataGridView1 为只读
DataGridView1.ReadOnly = true;此时,用户的新增行操作和删除行操作也被屏蔽了。

如果希望,DataGridView 内某个单元格不可编辑, 那么只要:

// 设置 DataGridView1 的第2列整列单元格为只读
DataGridView1.Columns[1].ReadOnly = true;

// 设置 DataGridView1 的第3行整行单元格为只读
DataGridView1.Rows[2].ReadOnly = true;

// 设置 DataGridView1 的[0,0]单元格为只读
DataGridView1[0, 0].ReadOnly = true;

2) 使用 EditMode 属性
DataGridView.EditMode 属性被设置为 DataGridViewEditMode.EditProgrammatically 时,用户就不能手动编辑单元格的内容了。但是可以通过程序,调用 DataGridView.BeginEdit 方法,使单元格进入编辑模式进行编辑。

DataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;

3) 根据条件设定单元格的不可编辑状态
当一个一个的通过单元格坐标设定单元格 ReadOnly 属性的方法太麻烦的时候,你可以通过 CellBeginEdit 事件来取消单元格的编辑。

// CellBeginEdit 事件处理方法
private void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
//是否可以进行编辑的条件检查
if (dgv.Columns[e.ColumnIndex].Name == “Column1″ && !(bool)dgv["Column2", e.RowIndex].Value)
{
// 取消编辑
e.Cancel = true;
}
}

——————————————————————————–
③ DataGridView 不显示最下面的新行:

通常 DataGridView 的最下面一行是用户新追加的行(行头显示 * )。如果不想让用户新追加行即不想显示该新行,可以将 DataGridView 对象的 AllowUserToAddRows 属性设置为 False。

// 设置用户不能手动给 DataGridView1 添加新行
DataGridView1.AllowUserToAddRows = false;
但是,可以通过程序: DataGridViewRowCollection.Add 为 DataGridView 追加新行。

补足: 如果 DataGridView 的 DataSource 绑定的是 DataView, 还可以通过设置 DataView.AllowAdd
属性为 False 来达到同样的效果。
——————————————————————————–
④ DataGridView 判断新增行:

DataGridView 的AllowUserToAddRows属性为True时也就是允许用户追加新行的场合下,DataGridView的最后一行就是新追加的行(*行)。
使用 DataGridViewRow.IsNewRow 属性可以判断哪一行是新追加的行。另外,通过DataGridView.NewRowIndex 可以获取新行的行序列号.
在没有新行的时候,NewRowIndex = -1。

——————————————————————————–
⑤ DataGridView 行的用户删除操作的自定义:

1) 无条件的限制行删除操作。
默认时,DataGridView 是允许用户进行行的删除操作的。如果设置 DataGridView对象的AllowUserToDeleteRows属性为 False 时, 用户的行删除操作就被禁止了。

// 禁止DataGridView1的行删除操作。
DataGridView1.AllowUserToDeleteRows = false;
但是,通过 DataGridViewRowCollection.Remove 还是可以进行行的删除。
补足: 如果 DataGridView 绑定的是 DataView 的话,通过 DataView.AllowDelete 也可以控制行的删除。

2) 行删除时的条件判断处理。
用户在删除行的时候,将会引发 DataGridView.UserDeletingRow 事件。 在这个事件里,可以判断条件并取消删除操作。

// DataGridView1 的 UserDeletingRow 事件
private void DataGridView1_UserDeletingRow( object sender, DataGridViewRowCancelEventArgs e)
{
// 删除前的用户确认。
if (MessageBox.Show(“确认要删除该行数据吗?”, “删除确认”,
MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
{
// 如果不是 OK,则取消。
e.Cancel = true;
}
}

——————————————————————————–
⑥ DataGridView 行、列的隐藏和删除:

1) 行、列的隐藏

// DataGridView1的第一列隐藏
DataGridView1.Columns[0].Visible = false;

// DataGridView1的第一行隐藏
DataGridView1.Rows[0].Visible = false;

2) 行头、列头的隐藏

// 列头隐藏
DataGridView1.ColumnHeadersVisible = false;

// 行头隐藏
DataGridView1.RowHeadersVisible = false;

3) 行和列的删除

‘ 删除名为”Column1″的列
DataGridView1.Columns.Remove(“Column1″);

‘ 删除第一列

DataGridView1.Columns.RemoveAt(0);
‘ 删除第一行
DataGridView1.Rows.RemoveAt(0);

4) 删除选中行

foreach (DataGridViewRow r in DataGridView1.SelectedRows)
{
if (!r.IsNewRow)
{
DataGridView1.Rows.Remove(r);
}
}

——————————————————————————–
⑦ DataGridView 禁止列或者行的Resize:

1) 禁止所有的列或者行的Resize

// 禁止用户改变DataGridView1的所有列的列宽
DataGridView1.AllowUserToResizeColumns = false;

//禁止用户改变DataGridView1の所有行的行高
DataGridView1.AllowUserToResizeRows = false;
但是可以通过 DataGridViewColumn.Width 或者 DataGridViewRow.Height 属性设定列宽和行高。

2) 禁止指定行或者列的Resize

// 禁止用户改变DataGridView1的第一列的列宽
DataGridView1.Columns[0].Resizable = DataGridViewTriState.False;

// 禁止用户改变DataGridView1的第一列的行宽
DataGridView1.Rows[0].Resizable = DataGridViewTriState.False;

关于 NoSet :
当 Resizable 属性设为 DataGridViewTriState.NotSet 时, 实际上会默认以 DataGridView 的 AllowUserToResizeColumns 和 AllowUserToResizeRows 的属性值进行设定。
比如: DataGridView.AllowUserToResizeColumns = False 且 Resizable 是 NoSet 设定时,Resizable = False 。

判断 Resizable 是否是继承设定了 DataGridView 的 AllowUserToResizeColumns 和 AllowUserToResizeRows 的属性值,
可以根据 State 属性判断。如果 State 属性含有 ResizableSet,那么说明没有继承设定。
3) 列宽和行高的最小值的设定

// 第一列的最小列宽设定为 100
DataGridView1.Columns[0].MinimumWidth = 100;

// 第一行的最小行高设定为 50
DataGridView1.Rows[0].MinimumHeight = 50;

4) 禁止用户改变行头的宽度以及列头的高度

// 禁止用户改变列头的高度
DataGridView1.ColumnHeadersHeightSizeMode =
DataGridViewColumnHeadersHeightSizeMode.DisableResizing;

// 设置用户改变行头的宽度
DataGridView1.RowHeadersWidthSizeMode =
DataGridViewRowHeadersWidthSizeMode.EnableResizing;
——————————————————————————–
⑧ DataGridView 列宽和行高自动调整的设定:

1) 设定行高和列宽自动调整

// 设定包括Header和所有单元格的列宽自动调整
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

// 设定包括Header和所有单元格的行高自动调整
DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
AutoSizeColumnsMode 属性的设定值枚举请参照 msdn 的 DataGridViewAutoSizeRowsMode 说明。

2)指定列或行自动调整

// 第一列自动调整
DataGridView1.Columns[0].AutoSizeMode =
DataGridViewAutoSizeColumnMode.DisplayedCells;
AutoSizeMode 设定为 NotSet 时, 默认继承的是 DataGridView.AutoSizeColumnsMode 属性。

3) 设定列头的高度和行头的宽度自动调整
// 设定列头的宽度可以自由调整
DataGridView1.ColumnHeadersHeightSizeMode =
DataGridViewColumnHeadersHeightSizeMode.AutoSize;

// 设定行头的宽度可以自由调整
DataGridView1.RowHeadersWidthSizeMode =
DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;

4) 随时自动调整
a, 临时的,让列宽自动调整,这和指定AutoSizeColumnsMode属性一样。
// 让 DataGridView1 的所有列宽自动调整一下。
DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

// 让 DataGridView1 的第一列的列宽自动调整一下。
DataGridView1.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.AllCells);上面调用的 AutoResizeColumns 和 AutoResizeColumn
当指定的是DataGridViewAutoSizeColumnMode.AllCells 的时候,参数可以省略。即:
DataGridView1.AutoResizeColumn(0) 和 DataGridView1.AutoResizeColumns()

b,临时的,让行高自动调整

// 让 DataGridView1 的所有行高自动调整一下。
DataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);

//让 DataGridView1 的第一行的行高自动调整一下。
DataGridView1.AutoResizeRow(0, DataGridViewAutoSizeRowMode.AllCells);上面调用的 AutoResizeRows 和 AutoResizeRow
当指定的是DataGridViewAutoSizeRowMode.AllCells 的时候,参数可以省略。即:DataGridView1.AutoResizeRow (0) 和 DataGridView1.AutoResizeRows()

c,临时的,让行头和列头自动调整

// 列头高度自动调整
DataGridView1.AutoResizeColumnHeadersHeight();

// 行头宽度自动调整
DataGridView1.AutoResizeRowHeadersWidth(
DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);
关于性能:
通过 AutoSizeColumnsMode 或者 AutoSizeRowsMode 属性所指定的单元格进行自动调整时,如果调整次数过于多那么将可能导致性能下降,
尤其是在行和列数比较多的情况下。在这时用 DisplayedCells 代替 AllCells 能减少非所见的单元格的调整,从而提高性能。
——————————————————————————–
⑨ DataGridView 冻结列或行

1) 列冻结
DataGridViewColumn.Frozen 属性为 True 时, 该列左侧的所有列被固定, 横向滚动时固定列不随滚动条滚动而左右移动。这对于重要列固定显示很有用。

// DataGridView1的左侧2列固定
DataGridView1.Columns[1].Frozen = true;
但是,DataGridView.AllowUserToOrderColumns = True 时,固定列不能移动到非固定列, 反之亦然。

2) 行冻结
DataGridViewRow.Frozen 属性为 True 时, 该行上面的所有行被固定, 纵向滚动时固定行不随滚动条滚动而上下移动。

// DataGridView1 的上3行固定
DataGridView1.Rows[2].Frozen = true;

——————————————————————————–
⑩ DataGridView 列顺序的调整

设定 DataGridView 的 AllowUserToOrderColumns 为 True 的时候, 用户可以自由调整列的顺序。
当用户改变列的顺序的时候,其本身的 Index 不会改变,但是 DisplayIndex 改变了。你也可以通过程序改变 DisplayIndex 来改变列的顺序。 列顺序发生改变时会引发 ColumnDisplayIndexChanged 事件:
// DataGridView1的ColumnDisplayIndexChanged事件处理方法
private void DataGridView1_ColumnDisplayIndexChanged(object sender,
DataGridViewColumnEventArgs e)
{
Console.WriteLine(“{0} 的位置改变到 {1} “,
e.Column.Name, e.Column.DisplayIndex);
}

 

 

—————-
⑪ 行头列头的单元格
[C#]
// 改变DataGridView1的第一列列头内容
DataGridView1.Columns[0].HeaderCell.Value = “第一列”; 

// 改变DataGridView1的第一行行头内容
DataGridView1.Rows[0].HeaderCell.Value = “第一行”;

// 改变DataGridView1的左上头部单元内容
DataGridView1.TopLeftHeaderCell.Value = “左上”;

另外你也可以通过 HeaderText 来改变他们的内容。
[C#]
// 改变DataGridView1的第一列列头内容
DataGridView1.Columns[0].HeaderText = “第一列”;

⑫ DataGridView 剪切板的操作
TOP
DataGridView.ClipboardCopyMode 属性被设定为 DataGridViewClipboardCopyMode.Disable 以外的情况时,「Ctrl + C」 按下的时候,被选择的单元格的内容会拷贝到系统剪切板内。格式有: Text, UnicodeText,Html, CommaSeparatedValue。可以直接粘贴到 Excel 内。

ClipboardCopyMode 还可以设定 Header部分是否拷贝: EnableAlwaysIncludeHeaderText 拷贝Header部分、EnableWithoutHeaderText 则不拷贝。默认是 EnableWithAutoHeaderText , Header 如果选择了的话,就拷贝。

1) 编程方式实现剪切板的拷贝

Clipboard.SetDataObject(DataGridView1.GetClipboardContent())

2) DataGridView 的数据粘贴

实现剪切板的拷贝比较容易,但是实现 DataGridView 的直接粘贴就比较难了。「Ctrl + V」按下进行粘贴时,DataGridView 没有提供方法,只能自己实现。

以下,是粘贴时简单的事例代码,将拷贝数据粘贴到以选择单元格开始的区域内。

[C#]
//当前单元格是否选择的判断
if (DataGridView1.CurrentCell == null)
return;
int insertRowIndex = DataGridView1.CurrentCell.RowIndex;

// 获取剪切板的内容,并按行分割
string pasteText = Clipboard.GetText();
if (string.IsNullOrEmpty(pasteText))
return;
pasteText = pasteText.Replace(” “, ” “);
pasteText = pasteText.Replace(‘ ‘, ‘ ‘);
pasteText.TrimEnd(new char[] { ‘ ‘ });
string[] lines = pasteText.Split(‘ ‘);

bool isHeader = true;
foreach (string line in lines)
{
// 是否是列头
if (isHeader)
{
isHeader = false;
continue;
}

// 按 Tab 分割数据
string[] vals = line.Split(‘ ‘);
// 判断列数是否统一
if (vals.Length – 1 != DataGridView1.ColumnCount)
throw new ApplicationException(“粘贴的列数不正确。”);
DataGridViewRow row = DataGridView1.Rows[insertRowIndex];
// 行头设定
row.HeaderCell.Value = vals[0];
// 单元格内容设定
for (int i = 0; i < row.Cells.Count; i++)
{
row.Cells[i].Value = vals[i + 1];
}

// DataGridView的行索引+1
insertRowIndex++;
}

________________________________________
⑬ DataGridView 单元格的ToolTip的设置

DataGridView.ShowCellToolTips = True 的情况下, 单元格的 ToolTip 可以表示出来。对于单元格窄小,无法完全显示的单元格, ToolTip 可以显示必要的信息。

1) 设定单元格的ToolTip内容
[C#]
// 设定单元格的ToolTip内容
DataGridView1[0, 0].ToolTipText = “该单元格的内容不能修改”;

// 设定列头的单元格的ToolTip内容
DataGridView1.Columns[0].ToolTipText = “该列只能输入数字”;

// 设定行头的单元格的ToolTip内容
DataGridView1.Rows[0].HeaderCell.ToolTipText = “该行单元格内容不能修改”;

2) CellToolTipTextNeeded 事件
在批量的单元格的 ToolTip 设定的时候,一个一个指定那么设定的效率比较低, 这时候可以利用 CellToolTipTextNeeded 事件。当单元格的 ToolTipText 变化的时候也会引发该事件。但是,当DataGridView的DataSource被指定且VirualMode=True的时候,该事件不会被引发。
[C#]
// CellToolTipTextNeeded事件处理方法
private void DataGridView1_CellToolTipTextNeeded(object sender,
DataGridViewCellToolTipTextNeededEventArgs e)
{
e.ToolTipText = e.ColumnIndex.ToString() + “, ” + e.RowIndex.ToString();
}

________________________________________
⑭ DataGridView 的右键菜单(ContextMenuStrip)

DataGridView, DataGridViewColumn, DataGridViewRow, DataGridViewCell 有 ContextMenuStrip 属性。可以通过设定 ContextMenuStrip 对象来控制 DataGridView 的右键菜单的显示。 DataGridViewColumn 的 ContextMenuStrip 属性设定了 除了列头以外的单元格的右键菜单。 DataGridViewRow 的 ContextMenuStrip 属性设定了除了行头以外的单元格的右键菜单。DataGridViewCell 的 ContextMenuStrip 属性设定了指定单元格的右键菜单。
[C#]
// DataGridView 的 ContextMenuStrip 设定
DataGridView1.ContextMenuStrip = this.ContextMenuStrip1;

// 列的 ContextMenuStrip 设定
DataGridView1.Columns[0].ContextMenuStrip = this.ContextMenuStrip2;
// 列头的 ContextMenuStrip 设定
DataGridView1.Columns[0].HeaderCell.ContextMenuStrip = this.ContextMenuStrip2;

// 行的 ContextMenuStrip 设定
DataGridView1.Rows[0].ContextMenuStrip = this.ContextMenuStrip3;

// 单元格的 ContextMenuStrip 设定
DataGridView1[0, 0].ContextMenuStrip = this.ContextMenuStrip4;
对于单元格上的右键菜单的设定,优先顺序是: Cell > Row > Column > DataGridView
⇒ CellContextMenuStripNeeded、RowContextMenuStripNeeded 事件
利用 CellContextMenuStripNeeded 事件可以设定单元格的右键菜单,尤其但需要右键菜单根据单元格值的变化而变化的时候。比起使用循环遍历,使用该事件来设定右键菜单的效率更高。但是,在DataGridView使用了DataSource绑定而且是VirtualMode的时候,该事件将不被引发。
[C#]
// CellContextMenuStripNeeded事件处理方法
private void DataGridView1_CellContextMenuStripNeeded(object sender,
DataGridViewCellContextMenuStripNeededEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
if (e.RowIndex < 0)
{
// 列头的ContextMenuStrip设定
e.ContextMenuStrip = this.ContextMenuStrip1;
}
else if (e.ColumnIndex < 0)
{
// 行头的ContextMenuStrip设定
e.ContextMenuStrip = this.ContextMenuStrip2;
}
else if (dgv[e.ColumnIndex, e.RowIndex].Value is int)
{
// 如果单元格值是整数时
e.ContextMenuStrip = this.ContextMenuStrip3;
}
}
同样,可以通过 RowContextMenuStripNeeded 事件来设定行的右键菜单。
[C#]
// RowContextMenuStripNeeded事件处理方法
private void DataGridView1_RowContextMenuStripNeeded(object sender,
DataGridViewRowContextMenuStripNeededEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
// 当”Column1″列是Bool型且为True时、设定其的ContextMenuStrip
object boolVal = dgv["Column1", e.RowIndex].Value;
Console.WriteLine(boolVal);
if (boolVal is bool && (bool)boolVal)
{
e.ContextMenuStrip = this.ContextMenuStrip1;
}
}

CellContextMenuStripNeeded 事件处理方法的参数中、「e.ColumnIndex=-1」表示行头、「e.RowIndex=-1」表示列头。RowContextMenuStripNeeded则不存在「e.RowIndex=-1」的情况。
________________________________________
⑮ DataGridView 的单元格的边框、 网格线样式的设定

1) DataGridView 的边框线样式的设定
DataGridView 的边框线的样式是通过 DataGridView.BorderStyle 属性来设定的。 BorderStyle 属性设定值是一个
BorderStyle 枚举: FixedSingle(单线,默认)、Fixed3D、None。

2) 单元格的边框线样式的设定
单元格的边框线的样式是通过 DataGridView.CellBorderStyle 属性来设定的。 CellBorderStyle 属性设定值是
DataGridViewCellBorderStyle 枚举。(详细参见 MSDN)
另外,通过 DataGridView.ColumnHeadersBorderStyle 和 RowHeadersBorderStyle 属性可以修改 DataGridView 的头部的单元格边框线样式。 属性设定值是 DataGridViewHeaderBorderStyle 枚举。(详细参见 MSDN)

3) 单元格的边框颜色的设定
单元格的边框线的颜色可以通过 DataGridView.GridColor 属性来设定的。默认是 ControlDarkDark 。但是只有在 CellBorderStyle 被设定为 Single、SingleHorizontal、SingleVertical 的条件下才能改变其边框线的颜色。同样,ColumnHeadersBorderStyle 以及 RowHeadersBorderStyle 只有在被设定为 Single 时,才能改变颜色。

4) 单元格的上下左右的边框线式样的单独设定
CellBorderStyle只能设定单元格全部边框线的式样。要单独改变单元格某一边边框式样的话,需要用到DataGridView.AdvancedCellBorderStyle属性。如示例:
[VB.NET]
‘ 单元格的上边和左边线设为二重线
‘ 单元格的下边和右边线设为单重线
DataGridView1.AdvancedCellBorderStyle.Top = _
DataGridViewAdvancedCellBorderStyle.InsetDouble
DataGridView1.AdvancedCellBorderStyle.Right = _
DataGridViewAdvancedCellBorderStyle.Inset
DataGridView1.AdvancedCellBorderStyle.Bottom = _
DataGridViewAdvancedCellBorderStyle.Inset
DataGridView1.AdvancedCellBorderStyle.Left = _
DataGridViewAdvancedCellBorderStyle.InsetDouble

同样,设定行头单元格的属性是: AdvancedRowHeadersBorderStyle, 设定列头单元格属性是:AdvancedColumnHeadersBorderStyle。
________________________________________
⑯ DataGridView 单元格表示值的自定义

通过CellFormatting事件,可以自定义单元格的表示值。(比如:值为Error的时候,单元格被设定为红色)
下面的示例:将“Colmn1”列的值改为大写。
[C#]
//CellFormatting 事件处理方法
private void DataGridView1_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;

// 如果单元格是“Column1”列的单元格
if (dgv.Columns[e.ColumnIndex].Name == “Column1″ && e.Value is string)
{
// 将单元格值改为大写
string str = e.Value.ToString();
e.Value = str.ToUpper();
// 应用该Format,Format完毕。
e.FormattingApplied = true;
}
}

CellFormatting事件的DataGridViewCellFormattingEventArgs对象的Value属性一开始保存着未被格式化的值。当Value属性被设定表示用的文本之后,把FormattingApplied属性做为True,告知DataGridView文本已经格式化完毕。如果不这样做的话,DataGridView会根据已经设定的Format,NullValue,DataSourceNullValue,FormatProvider属性会将Value属性会被重新格式化一遍。
________________________________________
⑰ DataGridView 用户输入时,单元格输入值的设定

通过 DataGridView.CellParsing 事件可以设定用户输入的值。下面的示例:当输入英文文本内容的时候,立即被改变为大写。
[C#]
//CellParsing 事件处理方法
private void DataGridView1_CellParsing(object sender,
DataGridViewCellParsingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;

//单元格列为“Column1”时
if (dgv.Columns[e.ColumnIndex].Name == “Column1″ &&
e.DesiredType == typeof(string))
{
//将单元格值设为大写
e.Value = e.Value.ToString().ToUpper();
//解析完毕
e.ParsingApplied = true;
}
}

________________________________________
⑱ DataGridView 新加行的默认值的设定

需要指定新加行的默认值的时候,可以在DataGridView.DefaultValuesNeeded事件里处理。在该事件中处理除了可以设定默认值以外,还可以指定某些特定的单元格的ReadOnly属性等。
[C#]
// DefaultValuesNeeded 事件处理方法
private void DataGridView1_DefaultValuesNeeded(object sender,
DataGridViewRowEventArgs e)
{
// 设定单元格的默认值
e.Row.Cells["Column1"].Value = 0;
e.Row.Cells["Column2"].Value = “-”;
}

原文地址:http://hi.baidu.com/iamheyjudy/blog/item/408e851b02e14b0d8718bf06.html

分享按钮

早间主播

1-101012092641

下在几天了才翻出来看,没想到这么给力.

看的我2次感动落泪……呵呵!

片尾曲不错,听听看!

http://www.yinyuetai.com/video/swf/131380/3/a.swf

分享按钮

上火

生闷气很容易上火啊!

分享按钮

爱用不用

我忍这没在客户面前说出这句话.

很想知道别人在实施软件的时候如果碰到这样的问题会怎么样处理.

 

实施和需求也有2-3个月了,上个系统就这么难!

 

分享按钮

周末

周末难得室友一起休假,本来准备把淘宝上淘的麻将开苞.结果他们个个都睡到12点.受不了他们.

看样子哪麻将只能放那收藏了.

等到下午都吃饱了睡足了才开始记得昨天叫着打麻将来着.这些人!

可是都到下午2点了,马上中国斯诺克公开赛决赛的上半场就要开打了.这下他们无奈了.

很期待看哪个什么特鲁姆普的表现啊,14岁就打出单杆147分.可以说是超级神童了.希望不要让我失望啊.

分享按钮

成功变更网站备案

3月10号快递的备案变更资料,今天终于是审批通过了.

有点搞,看发送时间2011年4月1号00:00

上图:

beian

 

 

分享按钮
Page 1 of 3123»