C# 参见RadioButton_checked从另一个表单更改的值
我正在编写一个小程序,可以处理CSV和XML之间的转换以及从XML到TXT的转换。在主窗体中,我插入了两个单选按钮,用户将单击它们开始所需的转换 到目前为止,我需要.cs文件:MainForm.cs和ConversionForm.cs 在MainForm.cs中,我将MainForm声明为static,以允许ConversionForm访问其方法C# 参见RadioButton_checked从另一个表单更改的值,c#,winforms,radio-button,C#,Winforms,Radio Button,我正在编写一个小程序,可以处理CSV和XML之间的转换以及从XML到TXT的转换。在主窗体中,我插入了两个单选按钮,用户将单击它们开始所需的转换 到目前为止,我需要.cs文件:MainForm.cs和ConversionForm.cs 在MainForm.cs中,我将MainForm声明为static,以允许ConversionForm访问其方法 public MainForm() { InitializeComponent(); } publi
public MainForm()
{
InitializeComponent();
}
public static MainForm mform = null;
。。。然后,我插入了检查更改的事件处理程序的函数:
public void CSVConversionRadio_CheckedChanged(object sender, EventArgs e)
{
this.CSVConversionRadio.Checked = true;
}
public void TXTConversionRadio_CheckedChanged(object sender, EventArgs e)
{
this.TXTConversionRadio.Checked = true;
}
在ConversionForm中,我有一个“Convert”按钮,它应该根据用户的输入选择处理转换
public void conversionButton_Click(object sender, EventArgs e)
{
if (MainForm.mform.CSVConversionRadio.Checked = true)
{
CSVConversion();
}
if (MainForm.mform.TXTConversionRadio.Checked = true)
{
TXTConversion();
}
}
我面临的问题是,当函数检查单选按钮的状态时,程序返回“null”,引发异常。在对代码进行一些更改之前,即声明静态函数
公共静态MainForm mform=null代码>
MainForm.mform.CSVConversionRadio.Checked始终返回“false”状态,可能是因为正在实例化新表单(转换),并且事件处理程序将其状态重置为默认状态
因此,以下是我的问题:
如何将单选按钮的当前值传递给转换表单,从而允许根据用户的选择执行转换功能
通常,我如何从另一个窗体引用属性、方法和字段,而不创建新实例,而只指向前一个仍然打开的实例
扔掉那个静态变量mform。如果保留空值,则无效。
相反,当您从MainForm调用ConversionForm的构造函数时,将MainForm的实例传递给ConversionForm的实例
ConversionForm conv = new ConversionForm(this);
然后在ConversionForm的构造函数中保存传入全局变量的实例
public partical class ConversionForm:Form
{
MainForm _currentInstanceMainForm = null
public ConversionFomr(MainForm f)
{
_currentInstanceMainForm = f;
}
}
现在,当您需要调用MainForm的公共方法时,可以使用在构建时传递的实例
public void conversionButton_Click(object sender, EventArgs e)
{
if (_currentInstanceMainForm.CSVConversionRadio.Checked == true)
{
CSVConversion();
}
if (currentInstanceMainForm.TXTConversionRadio.Checked == true)
{
TXTConversion();
}
}
但是,最好隔离MainForm的内部控件,不要让外部表单直接访问MainForm的控件。
要允许这种模式,您需要准备两个公共属性,每个外部表单都可以检查这些属性,以获取有关MainForm控件状态的信息
在MainForm中添加这两个公共属性
public bool CSVConversionRequired
{
get { return (this.CSVConversionRadio.Checked); }
}
public bool TXTConversionRequired
{
get { return (this.TXTConversionRadio.Checked); }
}
并将转换窗体更改为
public void conversionButton_Click(object sender, EventArgs e)
{
if (_currentInstanceMainForm.CSVConversionRequired == true)
CSVConversion();
if (currentInstanceMainForm.TXTConversionRequired == true)
{
TXTConversion();
}
}
表单之间共享信息的方式有多种
我认为一个简单的方法是创建一个两种形式都知道的中介类
public class ConversionContext : INotifyPropertyChanged {
private ConversionType type;
public ConversionType Type {
get { return type; }
set {
if (type != value) {
type = value;
onPropertyChanged("ConversionType");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void onPropertyChanged(string propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public enum ConversionType { None, Xls, Csv, Txt }
然后,在创建表单时,使用两个表单上的构造函数或属性将同一个ConversionContext的实例传递给它们。如果您正在使用一个属性,这就是如何做到的
private ConversionContext context;
public ConversionContext SharedContext {
get { return context; }
set {
if (context == value) {
return;
}
if (context != null) {
context.PropertyChanged -= onContextPropertyChanged;
}
context = value;
context.PropertyChanged += onContextPropertyChanged;
}
}
在主窗体中,可以为用户检查设置此类型的控件时添加事件处理程序
public void CSVConversionRadio_CheckedChanged(object sender, EventArgs e)
{
context.Type = ConversionType.Csv;
}
设置类型时,将触发PropertyChanged事件,您可以在表单中获取并响应该事件
private void onContextPropertyChanged(object sender, PropertyChangedEventArgs e) {
switch (context.Type) {
case ConversionType.Xls :
// check a checkbox that represents xls
break;
// handle the other file types
}
}
当按下转换表单中的按钮时,类型已设置
public void conversionButton_Click(object sender, EventArgs e) {
switch (context.Type) {
case ConversionType.Csv:
CSVConversion();
break;
case ConversionType.Txt:
TXTConversion();
break;
}
}
这也减少了表单之间的依赖关系,导致两者之间的差异。我已经编辑了您的标题。请参阅“”,其中共识是“不,他们不应该”。我认为您不需要在CheckChanged事件中再次设置复选框值。试着把这行注释掉,看看会发生什么。另外,你的意思不是如果(MainForm.mform.CSVConversionRadio.Checked=true)
。你的意思是if(MainForm.mform.CSVConversionRadio.Checked==true)
,这与if(MainForm.mform.CSVConversionRadio.Checked)
实际上,我现在改为if(MainForm.mform.CSVConversionRadio.Checked)但没有任何更改。正在抛出空引用异常。您在这里遇到了逻辑问题,可能对OOP有一些误解。如果mform为null并且从不指向MainForm的有效实例,那么您如何尝试从null引用中调用方法呢?Patrick,谢谢。还有,史蒂夫,谢谢你的解决方案。Patrick老实说我觉得你的解决方案太复杂了我无法部署。我试过了,但我得到的是一个例外而不是例外。我需要一个简单的例子,就像Steve的一样,这也给了我错误。你遇到了什么异常?Steve,在你的解决方案中,我用这个得到了一个错误。此处ConversionForm conv=新的转换形式(this);这里有两个错误。返回(this.TXTConversionRadio.Checked);vstudio expexts一组或get访问器…我想我要为covnersion创建两个不同的表单…@user1776401,请在我的答案上发表您的评论,否则SO系统不会通知我。您能告诉我错误消息吗?我冒昧地向properties.oops添加了get访问器,这真是一个信号。该睡觉了。谢谢帕特里克,谢谢史蒂夫。然而,经过一些尝试,我无法解决这个问题。完全按照您的建议进行编码会在某些元素上出现一些空异常。例如,在这里,如果(_currentInstanceMainForm.CSVConversionRequired==true)CSVConversion();编译器返回一个null异常,可能是因为:MainForm\u currentInstanceMainForm=null。是的,它最初为null,假设您的转换表单是由MainForm实例创建的,此时您将this引用传递给刚刚创建的转换表单实例。然后使用内部变量(至少在MainForm关闭之前)