近端时间开发一个winfrom项目和as 3.0的结合,费了老大劲了

本文介绍如何在WinForms应用程序中实现ComboBox控件的数据绑定及DataGridView的分页显示功能,包括设置显示字段、获取选定值及自定义数据绑定方法。

1 关于winfrom里comboBox下拉菜单的数据绑定和取值

    前台页面有comboBox控件名字叫cbB_squadCode,后台绑定

            BSquad bsquad = new BSquad();
            this.cbB_squadCode.DataSource = bsquad.GetDTAll();   //得到所有的数据
            this.cbB_squadCode.DisplayMember = "code";
            this.cbB_squadCode.ValueMember = "leader";

   取到绑定的数据:

            string SquadCode = this.cbB_squadCode.SelectedIndex.ToString();

           cbB_squadCode.SelectedIndex取到的是索引值,this.cbB_squadCode.SelectedValue 取到的是ValueMember的值

2数据源的绑定列表

自定的控件


        /// <summary>
        /// 数据绑定
        /// </summary>
        /// <param name="currentPage">当前页</param>
        /// <param name="nCurrent">当前记录数</param>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        private void Bind(int currentPage, int nCurrent, string id, string name, string starttime, string endtime)
        {
            int pagesize = 6;//每页数
            int TotalCount = Convert.ToInt32(bil.GetDT(id, name, starttime, endtime).Rows.Count.ToString());//总记录数
            int nStartPos = 0;       //当前页面开始记录行
            int nEndPos = 0;           //当前页面结束记录行

            int check = TotalCount % pagesize;
            int page = TotalCount / pagesize;
            if (check != 0)
            {
                page++;//实际总页面
            }

            if (currentPage == page)
            {
                nEndPos = TotalCount;
            }
            else
            {
                nEndPos = pagesize * currentPage;
            }

            nStartPos = nCurrent;


            DataTable dtInfo = bil.GetDT(id, name, starttime, endtime);
            DataTable dtTemp = dtInfo.Clone();


            for (int i = nStartPos; i < nEndPos; i++)
            {
                dtTemp.ImportRow(dtInfo.Rows[i]);
                nCurrent++;

            }


            this.gvResult.DataSource = dtTemp;
            this.gvResult.Columns.Clear();
            //手动绑定datagridview
            GridViewUtil.DisplayColumns(gvResult, "id1", "选择", "box");
           // GridViewUtil.DisplayColumns(gvResult, "image", "图片", "img");
            //GridViewUtil.DisplayColumns(gvResult, "code", "编号", "String");
            GridViewUtil.DisplayColumns(gvResult, "id", "id号", "String");
            GridViewUtil.DisplayColumns(gvResult, "title", "标题", "String");
           
           // GridViewUtil.DisplayColumns(gvResult, "sort", "所属类别", "int");
            GridViewUtil.DisplayColumns(gvResult, "releaser", "发布人", "String");
           // GridViewUtil.DisplayColumns(gvResult, "clicks", "点击次数", "int");
            GridViewUtil.DisplayColumns(gvResult, "writetime", "发布时间", "DataTime");
            //GridViewUtil.DisplayColumns(gvResult, "flag", "是否发布", "int");
            //GridViewUtil.DisplayColumns(gvResult, "area", "所属区域", "int");
           // GridViewUtil.DisplayColumns(gvResult, "informcontent", "内容", "String");

            //列表显示初始化
            //this.gvResult.Rows[0].Selected = false;
            gvResult.Columns["id1"].Width = 100;
            gvResult.Columns["id"].Width = 100;
            //gvResult.Columns["code"].Width = 50;
            //gvResult.Columns["image"].Width = 50;
            gvResult.Columns["title"].Width = 120;
            //gvResult.Columns["sort"].Width = 60;
            gvResult.Columns["releaser"].Width = 100;
            gvResult.Columns["writetime"].Width = 190;
            //gvResult.Columns["clicks"].Width = 60;
           // gvResult.Columns["flag"].Width = 80;
            //gvResult.Columns["area"].Width = 110;
            //gvResult.Columns["informcontent"].Width = 100;
            //初始化checkbox未选中

            foreach (DataGridViewRow row in this.gvResult.Rows)
            {
                row.Cells[0].Value = false;
            }
            //绑定页码相关信息
            PagerControl pager = new PagerControl(currentPage, pagesize, TotalCount, "跳转");
            pager.currentPageChanged += new EventHandler(pager_currentPageChanged);//页码变化 触发的事件
            this.panelPager.Controls.Add(pager);//在Panel容器中加入这个控件

        }

就这些了,希望给大家带来方便

 

<think> 我们有两个WinForm程序:程序A(包含TextBox)程序B(需要获取程序A中TextBox的文本) 由于是两个独立的应用程序,它们运行在不同的进程空间中,因此不能直接通过对象引用来访问。 解决方案通常是通过进程间通信(IPC)来实现。常见的IPC方式有: 1. 使用文件:程序A将TextBox文本写入一个文件,程序B读取该文件。 2. 使用共享内存:通过内存映射文件等方式。 3. 使用Windows消息:通过SendMessage发送消息,但要求两个程序都是WinForm且知道对方窗口句柄。 4. 使用网络通信:如TCP/UDP,命名管道等。 5. 使用剪贴板:程序A复制文本到剪贴板,程序B从剪贴板读取。 但是,根据用户的问题,他想要“开发一个WinForm程序获取另一个WinForm中TextBox的文本”,这里我们假设两个程序都是我们自己开发的,因此我们可以选择一种合适的IPC方式。 考虑到简单性实时性,我们可以使用Windows消息机制(SendMessage)或命名管道(Named Pipes)。这里我们介绍使用Windows消息的方法,因为它在WinForm之间通信较为直接,但需要注意的是,这种方法要求知道目标窗口的句柄。 步骤: 1. 在程序A中,获取包含TextBox的窗体的句柄(Handle)。 2. 在程序B中,获取程序A窗体的句柄(可以通过FindWindow函数查找窗口标题等方式)。 3. 程序B向程序A的窗体发送一个自定义消息(WM_GETTEXT或自定义消息)。 4. 程序A接收到消息后,将TextBox的文本发送回程序B。 但是,由于程序A可能没有预先设计接收消息并返回文本的功能,因此我们需要修改程序A以支持该功能。 另一种更简单的方式:使用剪贴板(如果用户允许)。程序A将文本复制到剪贴板,程序B读取剪贴板。但这样会干扰用户的剪贴板内容。 考虑到通用性简单性,这里我们使用命名管道。因为命名管道支持双向通信,且不受窗口句柄的限制。 由于用户要求开发两个WinForm程序,我们分别称为AppA(包含TextBox)AppB(获取AppA中的文本)。 使用命名管道的基本思路: 1. 在AppA中创建一个命名管道服务器,等待连接。 2. 在AppB中作为客户端连接到AppA的命名管道。 3. AppB发送请求,AppA收到请求后将其TextBox的文本发送给AppB。 但是,注意:AppA可能随时在文本框中输入,而AppB在需要的时候才获取。因此,我们可以让AppA在收到请求时发送当前文本框内容。 具体步骤: 对于AppA(服务器): a. 在程序启动时,启动一个管道服务器,等待客户端连接。 b. 当有客户端连接时,读取客户端发送的请求(可以是一个简单的字符串,如"GetText")。 c. 将TextBox的文本发送回客户端。 对于AppB(客户端): a. 用户触发某个操作(如点击按钮)时,连接到AppA的管道。 b. 发送请求字符串。 c. 读取AppA返回的文本并显示。 注意:管道通信是阻塞的,因此AppA需要在后台线程中运行管道服务器,避免阻塞UI线程。 下面我们分别给出两个程序的代码框架。 AppA(服务器端)代码示例: 在AppA中,我们首先添加一个TextBox(textBox1)一个Label(用于显示状态,可选)。然后在窗体加载时启动管道服务器线程。 注意:管道名称需要唯一,例如我们可以用程序名加GUID,但这里为了简单,我们使用一个固定的名称(确保两个程序都知道这个名称)。 使用`System.IO.Pipes`命名空间。 由于管道服务器需要一直运行,我们在后台线程中运行。 代码步骤: 1. 创建NamedPipeServerStream实例。 2. 等待客户端连接。 3. 读取客户端发送的请求(假设是"GetText")。 4. 将textBox1.Text发送给客户端。 5. 关闭当前连接,然后重新等待(以便下次请求)。 但是,由于我们只需要一次请求一次响应,也可以每次连接后关闭,然后重新创建。这里我们采用循环等待连接。 注意:在窗体关闭时,需要终止后台线程。 代码示例: ```csharp using System.IO.Pipes; using System.Threading; // 在窗体类中定义 private Thread pipeServerThread; private volatile bool isRunning = false; private void Form1_Load(object sender, EventArgs e) { isRunning = true; pipeServerThread = new Thread(PipeServer); pipeServerThread.IsBackground = true; pipeServerThread.Start(); } private void PipeServer() { try { while (isRunning) { using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("MyNamedPipe", PipeDirection.InOut)) { // 等待客户端连接 pipeServer.WaitForConnection(); // 读取请求 StreamReader reader = new StreamReader(pipeServer); string request = reader.ReadLine(); if (request == "GetText") { // 获取文本框的文本(需要跨线程访问UI控件,使用Invoke) string textToSend = ""; if (textBox1.InvokeRequired) { textBox1.Invoke(new Action(() => { textToSend = textBox1.Text; })); } else { textToSend = textBox1.Text; } // 发送文本 StreamWriter writer = new StreamWriter(pipeServer); writer.WriteLine(textToSend); writer.Flush(); } } } } catch (Exception ex) { // 处理异常 } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { isRunning = false; // 可以中断WaitForConnection,但这里我们通过设置isRunning为false并尝试连接一个客户端来跳出WaitForConnection // 为了简单,我们也可以不处理,因为线程是后台线程,程序关闭时线程会自动终止。 } ``` 注意:由于在后台线程中需要访问UI控件的Text属性,我们使用了Control.Invoke方法。 AppB(客户端)代码示例: 在AppB中,我们添加一个按钮一个TextBox(用于显示获取到的文本)。当点击按钮时,连接到命名管道,发送请求并接收响应。 ```csharp private void buttonGetText_Click(object sender, EventArgs e) { using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "MyNamedPipe", PipeDirection.InOut)) { try { pipeClient.Connect(5000); // 5秒超时 if (pipeClient.IsConnected) { StreamWriter writer = new StreamWriter(pipeClient); StreamReader reader = new StreamReader(pipeClient); // 发送请求 writer.WriteLine("GetText"); writer.Flush(); // 读取响应 string receivedText = reader.ReadLine(); textBoxReceived.Text = receivedText; // 显示到文本框 } } catch (Exception ex) { MessageBox.Show("获取文本失败: " + ex.Message); } } } ``` 注意:上述代码中,管道名称必须一致("MyNamedPipe")。 但是,这种方法有一个缺点:AppA必须作为服务器一直运行,且只能同时处理一个请求(因为我们在一个循环中每次只处理一个连接)。如果需要同时处理多个请求,可以使用多个线程处理连接,但在这个场景中,我们只需要简单的请求响应,所以可以接受。 另外,如果AppA没有运行,AppB连接时会超时或抛出异常,需要处理。 此外,由于命名管道在同一台机器上使用,所以服务器名称为"."。 以上代码提供了一个基本的框架,实际应用中可能需要更完善的错误处理线程管理。 另一种方法:使用Windows消息 如果两个窗体在同一个应用程序中(同一个进程),那么直接通过对象引用即可。但是用户问题明确是另一个WinForm程序(即另一个进程),所以只能通过进程间通信。 使用Windows消息的步骤: 1. 在AppA中,我们需要知道主窗体的句柄(this.Handle),并且需要重写WndProc方法来处理自定义消息。 2. 在AppB中,通过FindWindow(需要知道AppA窗体的类名窗口标题)来获取窗口句柄,然后发送消息。 自定义消息:我们可以定义一个消息(WM_USER + 某个数字)作为自定义消息。 但是,发送文本消息时,由于不能直接发送字符串,我们可以使用WM_COPYDATA消息(专门用于跨进程传递少量数据)。 具体步骤: AppA中: protected override void WndProc(ref Message m) { const int WM_COPYDATA = 0x004A; if (m.Msg == WM
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值