lzh 发布的文章

注册与注销ocx控件

一、注册

1.进入开始,点击运行。

2.在出现的框中键入regsvr32 C:xxxx.ocx 。(XXXX为控件名, C:为目录))(regsvr32E:控件的制作myOcxTestDebugmyOcxTest.ocx)

3.点击确认后等待出现提醒注册成功即可。

二、注销

1.进入开始,点击运行。

2.在出现的框中键入regsvr32 /u C:xxxx.ocx 。(XXXX为控件名, C:为目录)(regsvr32 /u E:控件的制作myOcxTestDebugmyOcxTest.ocx

3.点击确认后等待出现提醒注销成功即可。

怎么用C#写一个控件库

控件库,说白了,就是个类库项目。不过这个类库内定义了一系列自定义的控件。整个项目(类库+调用项目)结构大概是这个样

2018-07-06_140447.png

请忽略Class2ClassDiagram1.cd,这是我之前一个博文

用到的项目,留下来也无关紧要。UserControl2.cs就是我们的一个控件了。长这个样

2018-07-06_141003.png

一个TextBox下面有一条线,线宽等于文本框的宽等于整个控件的宽。当然,这需要在cs代码中做一些调整(设置属性或是什么)。代码长这个样,仅供参考

2018-07-06_141344.png

private int width;

定义了一个字段,用来指示控件的宽度,private。然后定义了一个属性,也是用来指示控件宽度,public。这样在类外访问控件宽度需通过属性,而不是直接把字段暴露给外部。

[Description("控件宽度"), Category("自定义属性")]
public int selfWidth
{
    get
    {
        return width;
    }
    set
    {
        this.width = value;
        this.Width = value;
        this.txtBox.Width = value;
        this.pictureBox.Width = value;
    }
}

其中

[Description("控件宽度"), Category("自定义属性")]

加上这行表明这个属性代表了控件宽度,后面的Category是分组情况。这行的意义是用了这个控件之后,就能在当前窗体设计器上面方便地改动属性值,就像这样

2018-07-06_142510.png

还有最后一段代码

private void UserControl1_SizeChanged(object sender, EventArgs e)
{
    this.selfWidth = this.Width;
}

尽管这个控件在主调窗体加载完之后大小就固定了,但是仍要增加控件尺寸改变事件。这样做是为了保证控件在窗体设计阶段拖拽能即时地调整自己相关的属性,而不至于外壳改变了,而里面的东西却还是老样子。

最后在我们需要用到这个控件的项目中调用相关dll就OK了。

写控件库一点都不难,只需要同样的过程重复N遍再加上一点创意,必要时还需要用点别人的东西。

用Visual Studio命令提示工具导出dll API 列表

每个版本的Visual Studio都会附带这个工具。在vs安装目录下的VC\bin目录下。也可从菜单中VS对应的菜单目录通过点击快捷方式访问。

不知道怎么使用dumpbin输入dumpbin /?即可。直接输入help会发现对应的提示列表中没有dumpbin命令。这是应为此时的提示是如何使用控制台应用程序的帮助。Microsoft玩了个小把戏,实际上只是以管理员的身份运行cmd.exe程序而已。只是当运行这个命令提示工具时,它把目录设置到安装目录下的VC目录。

导出dll的API到桌面可这样写

dumpbin /exports /out:桌面路径\a.txt c:\windows\system32\kernel.dll

移动DataGridView选中行

//向上移动
private void button4_Click(object sender, EventArgs e)
{
    //未选中
    if (dataGridView1.SelectedRows.Count==0)
    {
        return;
    }

    //首行
    if (dataGridView1.SelectedRows[0].Index==0)
    {
        return;
    }

    int selectedItemIndex = dataGridView1.SelectedRows[0].Index;

    //选中行的上一行的 空白副本
    DataGridViewRow dgvRow0 = (DataGridViewRow)dataGridView1.SelectedRows[0].Clone();

    //选中行的上一行的值存在对应副本里
    dgvRow0.Cells[0].Value = dataGridView1.Rows[selectedItemIndex - 1].Cells[0].Value;
    dgvRow0.Cells[1].Value = dataGridView1.Rows[selectedItemIndex - 1].Cells[1].Value;
    dgvRow0.Cells[2].Value = dataGridView1.Rows[selectedItemIndex - 1].Cells[2].Value;
    dgvRow0.Cells[3].Value = dataGridView1.Rows[selectedItemIndex - 1].Cells[3].Value;

    //用选中行覆盖掉上一行
    dataGridView1.Rows[selectedItemIndex - 1].Cells[0].Value = dataGridView1.Rows[selectedItemIndex].Cells[0].Value;
    dataGridView1.Rows[selectedItemIndex - 1].Cells[1].Value = dataGridView1.Rows[selectedItemIndex].Cells[1].Value;
    dataGridView1.Rows[selectedItemIndex - 1].Cells[2].Value = dataGridView1.Rows[selectedItemIndex].Cells[2].Value;
    dataGridView1.Rows[selectedItemIndex - 1].Cells[3].Value = dataGridView1.Rows[selectedItemIndex].Cells[3].Value;

    //用上一行的副本覆盖掉选中行
    dataGridView1.Rows[selectedItemIndex].Cells[0].Value = dgvRow0.Cells[0].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[1].Value = dgvRow0.Cells[1].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[2].Value = dgvRow0.Cells[2].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[3].Value = dgvRow0.Cells[3].Value;

    //将移动后的行设为选中行
    dataGridView1.Rows[selectedItemIndex - 1].Selected = true;
}
//向下移动
private void button5_Click(object sender, EventArgs e)
{
    //未选中
    if (dataGridView1.SelectedRows.Count == 0)
    {
        return;
    }

    //最后一行
    if (dataGridView1.SelectedRows[0].Index == dataGridView1.RowCount-1)
    {
        return;
    }

    int selectedItemIndex = dataGridView1.SelectedRows[0].Index;

    //选中行的下一行的 空白副本
    DataGridViewRow dgvRow0 = (DataGridViewRow)dataGridView1.SelectedRows[0].Clone();

    //选中行的下一行的值存在对应副本里
    dgvRow0.Cells[0].Value = dataGridView1.Rows[selectedItemIndex + 1].Cells[0].Value;
    dgvRow0.Cells[1].Value = dataGridView1.Rows[selectedItemIndex + 1].Cells[1].Value;
    dgvRow0.Cells[2].Value = dataGridView1.Rows[selectedItemIndex + 1].Cells[2].Value;
    dgvRow0.Cells[3].Value = dataGridView1.Rows[selectedItemIndex + 1].Cells[3].Value;

    //用选中行覆盖掉下一行
    dataGridView1.Rows[selectedItemIndex + 1].Cells[0].Value = dataGridView1.Rows[selectedItemIndex].Cells[0].Value;
    dataGridView1.Rows[selectedItemIndex + 1].Cells[1].Value = dataGridView1.Rows[selectedItemIndex].Cells[1].Value;
    dataGridView1.Rows[selectedItemIndex + 1].Cells[2].Value = dataGridView1.Rows[selectedItemIndex].Cells[2].Value;
    dataGridView1.Rows[selectedItemIndex + 1].Cells[3].Value = dataGridView1.Rows[selectedItemIndex].Cells[3].Value;

    //用下一行的副本覆盖掉选中行
    dataGridView1.Rows[selectedItemIndex].Cells[0].Value = dgvRow0.Cells[0].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[1].Value = dgvRow0.Cells[1].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[2].Value = dgvRow0.Cells[2].Value;
    dataGridView1.Rows[selectedItemIndex].Cells[3].Value = dgvRow0.Cells[3].Value;

    //将移动后的行设为选中行
    dataGridView1.Rows[selectedItemIndex + 1].Selected = true;

}

效果如下:

AA

循环遍历DataGridView各行某列数据

如此做

foreach (DataGridViewRow dgr in dataGridView1.Rows)
{
    if (dgr.Cells["Column1"].Value == null)
    {
        break;
    }
    label1.Text += dgr.Cells["Column1"].Value.ToString() + " ";
}           

若某行某列无值,dgr.Cells["Column1"].Value.ToString()获取值就会异常。