C#问题...Form2怎么获取Form1的按钮事件!..
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#问题...Form2怎么获取Form1的按钮事件!..相关的知识,希望对你有一定的参考价值。
当Form1的某个Button触发事件的时候,Form2捕获
是想知道是那个按钮吗?我在网上看了点,自己看看是不是有帮助
对于窗体间的数据传递,是刚开始从事.Net窗体应用程序开发人员碰到的一个常见问题,在此讲几个常见的实现方式。此节内容适用于模式窗体或非模式窗体,部分方式延伸到一般类的操作。
(1)构造函数参数传递
通过构造函数传递参数应该是比较基本的参数传递方式,重载构造函数,通过带参数的构造函数来实例化窗体。
在窗体类内部定义参数变量,
private object myParams;
实现构造函数,
public OptionForm(object parameters)
InitializeComponent();
this.myParams = parameters;//设置参数引用
实例化窗体,
OptionForm form = new OptionForm( myParams );
在实际使用过程中,需要注意传入的是引用类型还是值类型,处理方式会有所不同。
(2)使用窗体的属性
说起属性关联,上面已经提到过Form.Owner属性,下面笔者根据MSDN文档来比较完整的讲一下,大部分的文字来自MSDN文档,为保证其完整性,对其中一些属性描述进行了扩展。
Form.Owner 属性。获取或设置拥有此窗体的窗体。
语法,public Form Owner get; set;
若要使某窗体归另一个窗体所有,可为其 Owner 属性分配一个对将成为所有者的窗体的引用。当一个窗体归另一窗体所有时,它便随着所有者窗体最小化和关闭。例如,如果 Form2 归窗体 Form1 所有,则关闭或最小化 Form1 时,Form2 也会关闭或最小化。并且附属窗体从不显示在其所有者窗体后面。可以将附属窗体用于查找和替换窗口之类的窗口,当选定所有者窗体时,这些窗口不应消失。
Form.OwnedForms 属性。获取 Form 对象的数组,这些对象表示此窗体拥有的所有窗体。
语法,public Form[] OwnedForms get;
此属性返回包含此窗体拥有的所有窗体的数组。要使某窗体归另一个窗体所有,可调用 AddOwnedForm 方法。分配给所有者窗体的窗体将保持被拥有状态,直到调用了 RemoveOwnedForm 方法。如果窗体是多文档界面 (MDI) 父窗体,则除了当前打开的所有 MDI 子窗体外,此属性将返回所有显示的窗体。
Form.MdiChildren 属性。获取窗体的数组,这些窗体表示以此窗体作为父级的多文档界面 (MDI) 子窗体。
语法,public Form[] MdiChildren get;
此属性使您得以获取对当前在某 MDI 父窗体中打开的所有 MDI 子窗体的引用。若要创建 MDI 子窗体,请将要成为 MDI 父窗体的 Form 分配给该子窗体的 MdiParent 属性。可以使用此属性依次通过所有 MDI 子窗体,以执行一些操作,如当 MDI 父窗体关闭时将数据保存到数据库中,或者根据应用程序中执行的操作更新子窗体上的字段。
Form.MdiParent 属性。获取或设置此窗体的当前多文档界面 (MDI) 父窗体。
语法,public Form MdiParent get; set;
若要创建 MDI 子窗体,请将要成为 MDI 父窗体的 Form 分配给该子窗体的 MdiParent 属性。可以从某 MDI 子窗体使用此属性来获取所有子窗体都需要的全局信息或者调用对所有子窗体执行操作的方法。
Form.ActiveForm 静态属性。获取此应用程序的当前活动窗体。
语法,public static Form ActiveForm get;
表示当前活动窗体,或者如果没有活动窗体,则为空引用。可以使用此方法获得对当前活动窗体的引用,以在该窗体或其控件上执行操作。
Form.ActiveMdiChild 属性。获取当前活动的多文档界面 (MDI) 子窗口。
语法,public Form ActiveMdiChild get;
返回表示当前活动的 MDI 子窗口的 Form,或者如果当前没有子窗口,则返回 空引用。可使用此方法确定 MDI 应用程序中是否有任何打开的 MDI 子窗体。也可使用此方法从 MDI 子窗口的 MDI 父窗体或者从应用程序中显示的其他窗体对该 MDI 子窗口执行操作。
ContainerControl.ParentForm 属性。获取将容器控件分配给的窗体。
语法,public Form ParentForm get;
将容器控件分配给的 Form。
(3)使用公共属性(念时注:我比较常用这种方式)
使用公共属性也是一种比较常用的方式,通过窗体设计器添加的控件默认访问修饰符为private级别,可以设置成public或Internal(在程序集内部可见)来对外公开。比如对窗体中的Button进行公开,那就可以访问Button的相关属性,同时也可以注册事件或撤销事件注册。如,
OptionForm form = new OptionForm();
form.buttonOK.Click += new EventHandler(buttonOK_Click);
form.ShowDialog();
对于只允许读取访问或修改访问的控件或变量可以通过属性来控制。对(1)方式进行修改,去除重载构造函数,增加属性也可以实现同样的效果。
public object MyParams
get return this.myParams;
set this.myParams = value;
(4)使用公共方法
使用公共方法类似于属性,对上面的同等实现如下,
//获取参数
public object GetParams()
return this.myParams;
//设置参数
public void SetParams(object myParams )
this.myParams = myParams;
(5)使用静态类该方式可以简单的理解为静态变量全局共享,通过下面代码能够比较清楚的理解,先来定义静态类,
public static class ParameterSettings
//公共静态变量
public static string Username = "Zhengzuo";
//私有静态变量
private static string userRole = "Administrators";
//私有静态变量
private static string password = "http://blog.csdn.net/zhzuo";
//内部属性
internal static string UserRole
get return userRole;
//公共属性
public static string Password
get return password;
private set password = value;
在需要访问的地方通过以下方式进行,
string username = ParameterSettings.Username;
string password = ParameterSettings.Password;
string userRole = ParameterSettings.UserRole;
ParameterSettings.Username = "郑佐";//修改成新用户名
(6)窗体实现Singleton模式
Singleton模式是我们开发过程中最常用的模式之一。在技术社区经常看到有人谈及对主窗体实现Singleton,但个人认为这不是一种妥当的做法,因为没有这个必要。这里通过另一个自定义类来进行演示。假设UserLoginInfo类用来保存登录系统后的用户凭据。
/*==============================================
程序 郑佐 2006-4-23 http://blog.csdn.net/zhzuo
==============================================*/
public class UserLoginInfo
//实现Singleton模式,线程安全。
private readonly static UserLoginInfo currentUserInfo = new UserLoginInfo();
//提供全局访问点
public static UserLoginInfo CurrentUserInfo
get return currentUserInfo;
//阻止显式实例化,但不能阻止反射方式调用。
private UserLoginInfo()
//公共变量
public string Username;
//私有变量
private static string userRole;
//私有变量
private static string password;
//内部属性
internal string UserRole
get return userRole;
set userRole = value;
//公共属性
public string Password
get return password;
internal set password = value;
在其他代码中进行访问,
UserLoginInfo.CurrentUserInfo.Username ="郑佐";
UserLoginInfo.CurrentUserInfo.UserRole = "dotnetlover";
UserLoginInfo.CurrentUserInfo.Password = "http://blog.csdn.net/zhzuo";
对于Singleton模式的实现方式有很多,编写时需要考虑是否需要保证实例访问的线程安全问题,以免引发不可预料的情况,为了提高性能可以考虑惰性实例化。关于Singleton模式的更多信息可以参考另一篇文章。
(7)发布事件进行订阅
通过事件来传递参数应该说是一种推的实现方式,在产生事件时进行被动的获取相关数据。这里将通过一个自定义事件来演示数据的传输。
在自定义事件时,标准的做法都会先定义一个事件参数类,要么直接使用基类EventArgs,或者从EventArgs继承实现自己的参数类,假设自定义基类取名为OptionSettingEventArgs,
//选项设置事件参数类
public class OptionSettingEventArgs : EventArgs
private string changedPath;
//构造函数
public OptionSettingEventArgs(string changedPath)
this.changedPath = changedPath;
//读取参数
public string ChangedPath
get return this.changedPath;
以上参数类只包含一个修改后的路径参数。接下去我们要对原先的OptionForm窗体增加事件定义,这里使用.net 2.0中提供的泛型类来实现。
//定义事件
public event EventHandler<OptionSettingEventArgs> OptionSettingChanged;
编写事件引发程序如下,
//引发OptionSettingChanged事件
protected virtual void OnOptionSettingChanged(OptionSettingEventArgs e)
if (OptionSettingChanged != null)
OptionSettingChanged(this, e);
对文件目录选择按钮事件处理程序进行修改来实现事件激发,并没有考虑直接从文本框直接数据输入方式。
//通过目录对话框设置新的路径
private void buttonBrowser_Click(object sender, EventArgs e)
FolderBrowserDialog dialog = new FolderBrowserDialog();
DialogResult result = dialog.ShowDialog(this);
if (result == DialogResult.OK)
if(this.textBoxPath.Text != dialog.SelectedPath)
this.textBoxPath.Text = dialog.SelectedPath;
OptionSettingEventArgs args = new OptionSettingEventArgs(dialog.SelectedPath);
OnOptionSettingChanged(args);
好了,一切准备工作完成,调用代码如下,
OptionForm form = new OptionForm();
//注册事件
form.OptionSettingChanged += new EventHandler (form_OptionSettingChanged);
form.ShowDialog();
通过以下事件处理程序来验证其正确性,
private void form_OptionSettingChanged(object sender, OptionSettingEventArgs e)
string newPath = e.ChangedPath;
MessageBox.Show(this, String.Format("新路径为“0”。", newPath), "提示");
不知大家读了之后觉得怎么样,我觉得受益匪浅,感觉讲得很仔细,很全面,而且通俗易懂,希望你们也能有同样的感受。 参考技术A 您好,
您的问题可以这样解决:
在Form2中对外公布一个接口(Public方法),在Form1中把这个方法挂到Button的Click事件委托上,实现的代码如下:
public partial class Form1 : Form
public Form1()
InitializeComponent();
Form2 frm = new Form2();
this.button1.Click+=new EventHandler(frm.OnForm1ButtonClick);
private void button1_Click(object sender, EventArgs e)
Form2公布了OnForm1ButtonClick方法,代码如下:
public void OnForm1ButtonClick(object sender, EventArgs e)
MessageBox.Show("I got it!");
这样,当在Form1中点击按钮的时候,Form2会收到通知并作出相应的响应。
需要注意的一点是,Form2中的OnForm1ButtonClick方法签名必须符合事件处理过程的签名,也就是(object sender, EventArgs e)并且是Void类型。
当然,您也可以在Form1的Button_Click事件中调用Form2中的方法达到同样的效果。
希望这些信息对您有帮助。
WPF Form C#提交按钮到excel
【中文标题】WPF Form C#提交按钮到excel【英文标题】:WPF Form C# submit button to excel 【发布时间】:2022-01-13 13:59:57 【问题描述】:我正在尝试获取在 Visual Studio WPF C# 中创建的表单以提交到新的 excel 工作簿,该工作簿将保存到共享网络驱动器上。我进行了一些挖掘以试图找到最佳解决方案,并且遇到了 NPOI,但与我需要做的相比,所有解决方案似乎都相当复杂。是否有一些简单的资源可供我参考以简单地创建工作簿并将数据插入特定单元格 - 然后保存?
我在 NuGet 中看到的两个相关包是 DotNetCore.NPOI 和我应该使用的 NPOI?
到目前为止我尝试过的是:
private void Button_Click(object sender, RoutedEventArgs e)
using (var fs = new FileStream("Result12345.xlsx", FileMode.Create, FileAccess.Write))
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Sheet1");
workbook.Write(fs);
MessageBox.Show("Form submitted successfully");
这被输出到:项目文件夹\bin\Debug\net6.0-windows,它似乎创建了工作簿并保存(假设我需要做的就是把网络驱动器的路径放在文件流中然后这应该很容易)但是我如何将数据插入到单元格特定的单元格中?
【问题讨论】:
我可以使用 (var fs = new FileStream(@"\\ipaddress\sharename\Result12345.xlsx", FileMode.Create, FileAccess.写)) 【参考方案1】:我已经通过互操作 COM 库使用 Microsoft Excel,应该可以通过添加作为参考直接在您的 WPF 应用程序中使用。
首先,在解决方案资源管理器中,打开引用,右键单击并添加引用。
然后,选择您现在或将来有兴趣使用的 Office 库,例如其他应用程序。
在任何代码的顶部,您将添加“使用”子句
using Microsoft.Office.Interop.Excel;
using System;
这里有一个示例代码 sn-p,因此您可以控制任何活动的工作簿、工作表、循环显示显式行/列以及获取给定单元格的文本。
public void tryingExcel()
var SomeSampleFile = @"C:\Users\Public\SomeExcelFile.xlsx";
//Start Excel and get Application object.
var XL = new Microsoft.Office.Interop.Excel.Application();
XL.DisplayAlerts = false;
XL.Workbooks.Add();
// _Workbook and _Worksheet are part of Microsoft.Office.Interop.Excel
// via "using" clause at top of code
_Workbook wb = XL.ActiveWorkbook;
wb.Sheets.Add();
_Worksheet ws = wb.ActiveSheet;
ws.Cells[2, 1] = "Date/Time:";
ws.Cells[2, 2] = DateTime.Now;
for (var ir = 4; ir < 10; ir++)
ws.Cells[ir, 2] = "testing " + ir;;
for (var ir = 4; ir < 10; ir++)
ws.Cells[ir, 4] = ws.Cells[ir, 2].Text.Trim();
XL.ActiveWorkbook.SaveAs(SomeSampleFile, XlFileFormat.xlOpenXMLWorkbook,
Type.Missing, Type.Missing, false, false,
XlSaveAsAccessMode.xlNoChange,
XlSaveConflictResolution.xlLocalSessionChanges,
Type.Missing, Type.Missing, Type.Missing, false);
XL.Quit();
【讨论】:
【参考方案2】:我是这样想的:
private void Button_Click(object sender, RoutedEventArgs e)
using (var fs = new FileStream(@"\\ipaddress\sharename\Result12345.xlsx", FileMode.Create, FileAccess.Write))
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Sheet1");
//define cell to insert into
var cellTest = excelSheet.CreateRow(0).CreateCell(0);
//set cell value
cellTest.SetCellValue("Hello?");
//save the excel sheet
workbook.Write(fs);
MessageBox.Show("Form submitted successfully");
我想我只是不明白为什么当它们已经存在时我必须创建一个行/单元格。而不是设置类似Cell(0,1).value = "Something"
【讨论】:
您正在创建一个新的空工作表。尚无现有单元格。以上是关于C#问题...Form2怎么获取Form1的按钮事件!..的主要内容,如果未能解决你的问题,请参考以下文章