C#怎样在一个窗体上执行另一个窗体的按钮,不能用new啊!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#怎样在一个窗体上执行另一个窗体的按钮,不能用new啊!相关的知识,希望对你有一定的参考价值。

用事件回调,看一点我的代码
在Form1里面写一个方法,用来修改label
在Form2里面写:
public delegate void SetMainFormTopMostHandle(bool topmost);
public event SetMainFormTopMostHandle SetMainFormTopMost;
声明一个委托和事件
然后在f2.Show()打开f2之前,加一句:
Form2 f2 = new Form2 ();

f2.SetMainFormTopMost += new Form2.SetMainFormTopMostHandle(MainForm_SetMainFormTopMost);
f2.Show();
这里面MainForm_SetMainFormTopMost就是你用来修改label的方法(回调函数)
SetMainFormTopMostHandle、SetMainFormTopMost你自己写名字
大致就是为f2创建一个用来修改label的事件,然后把修改label的方法绑定到这个事件上,启动f2,在f2中执行这个事件,就是SetMainFormTopMost(true)这样写 (参数要和委托的那个声明一致)
那么就会调用F1中绑定的那个方法

f2.SetMainFormTopMost += new Form2.SetMainFormTopMostHandle(MainForm_SetMainFormTopMost);
这句最关键,你输入到+=之后,按两下Tab,他会自动给你生成回调函数
参考技术A 如果自动升级程序也是C#写的,并且你没法修改它代码的话……

MSDN Magazine 2006 四月刊上曾经发表过一篇关于 .NET 下的Spy++工具ManagedSpy,其中就涉及到了跨进程修改其他WinForm应用程序控件属性的的技术,并且有完整源码下载。但是比较复杂,还需要一个C++写的库ManagedSpyLib(也有源码)来配合——主要是因为还需要使用钩子来注入代码到目标应用程序中去等。

我下载编译调试通过了,的确可以修改其它进程WinForm控件的属性(比如设置按钮的Visible及Enabled属性)。

最关键的是引用那个C++写的ManagedSpyLib库之后,使用类似下面的代码即可修改其它进程控件的属性了:

namespace ManagedSpyTester

using System.Diagnostics;
using Microsoft.ManagedSpy;

class Program

static void Main()

Process[] p = Process.GetProcessesByName("MyAutoUpdate");

if (p.Length == 0)

return;


ControlProxy proxy = ControlProxy.FromHandle(p[0].MainWindowHandle);
foreach (ControlProxy child in proxy.Children)

if (child.GetComponentName() == "btnChange")

child.SetValue("Enabled", true);
child.SetValue("Visible", true);
break;






不过ManagedSpyLib的代码如果想要在Vista/Win7(打开了UAC的情况下)正常运行,需要稍作修改(很小);而且要确保自动升级程序和客户端主程序是在同一个权限级别下运行(比如都是管理员身份或者都是非管理员身份),否则无法存取在另一个权限级别下运行进程的控件属性。此外,如果系统的.NET版本是3.5/4.0以上,也需要稍作改动(很小),因为它原来的代码假定的是2.0版本。

楼主可以先自己把代码下载下来试试用用看,如果不行可以再找我。

相关网址:

___________________________
补充:

唉,是我想太多了,把问题弄复杂了。因为Visible和Enabled都是最基本的窗口属性,所以实际上用基本的Windows API就可以搞定了。

先添加下面几句话:
[DllImport("user32.dll")]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

然后在你拿到按钮的窗口句柄hWnd之后,加入如下代码:

ShowWindow(hWnd, 1);
EnableWindow(hWnd, true);

所以这样的说的话,应该是采纳“坂井悠二の阴谋”这位朋友的答案,是他先提出了使用这两个API的主意。

————————————
补充:
会不会是hWnd找错了?要不你用Spy++抓一下那个按钮看看……
我这边做了一个简单的试验,是可行的。

哦,也有可能是这个原因:
你用的Windows是什么版本?如果是Vista、Win7或者Win2008,而且UAC默认是开启的话,那么如果自动升级程序是“以管理员身份运行”而你的客户端程序不是(或者正好相反的情形),那此时EnableWindow和ShowWindow是没有效果的。也就是两个程序必须运行在同一个安全级别下面。这应该是Vista和Win7上UAC的User Interface Privilege Isolation(UIPI)保护的结果,防止低安全级别的恶意应用篡改高安全级别应用的状态。

不过,也只是我的猜想罢了,楼主可以自己试验一下看看。
参考技术B 一般只有用 window.open打开的窗口 才能 互相操作, 在子窗口中用 window.opener 这样调用父窗口 当然你可以用window.opener.方法 调用父窗口的方法 window.opener.document 访问父窗口的元素
其次还有模态窗口, 但它只在IE被支持,一般用的人不多
参考技术C 用delegate 委托事件

C#中怎样在一个窗体引用另一个窗体的变量

这个简单。
代码如下:
假设form1中变量的定义为:public
string
form1Str
=
"form1";
在form2中:form1
myForm1
=
new
form1();
string
form2Str
=
myForm1.form1Str;
这样就可以获取到form1中变量的引用了!
不过建议不要这么用,可以使用属性来做。
代码如下:
在form1中:private
string
form1Str;
public
string
Form1Str

get

return
form1Str;

set

form1Str
=
value;


在form2中代码相似:form1
myForm1
=
new
form1();
string
form2Str
=
myForm1.Form1Str;
这样就符合面向对象的封装原则了!
参考技术A 将变量在A窗体中设为全局变量
假设为public
static
string
a;
在控件的value_change事件中赋值:a=控件名.Text;
因为a是静态全局变量,所以B窗体使用到a值的时候直接用
A.a即可访问到;至于是赋值还是代入运算什么的都是A.a即可取到
参考技术B 2个窗口有关系的话:
from2
f
=
new
from2();
f.变量=f1的变量;
f.show();
然后在FORM2中就可以用啦。
要不就public
static
参考技术C 把这个变量定义为public
static
string;
然后在form1中使用Form2.这个变量

以上是关于C#怎样在一个窗体上执行另一个窗体的按钮,不能用new啊!的主要内容,如果未能解决你的问题,请参考以下文章

【C# panel】怎样能使填充窗体后的panel响应一下鼠标事件呢?

c#如何实现关闭当前窗体并打开另一个已经创建的窗体。

c#如何单击按钮显示另一个窗体?

C#中如何在一个窗体中调用另一个窗体控件中的数据?

VS里用C#如何实现点击一个按钮立即弹出另一个窗体?

C#中怎样在一个窗体引用另一个窗体的变量