我正在编写一个应该处理CSV和XML之间以及从XML到TXT之间转换的小程序。在主窗体中,我插入了两个单选按钮,用户将单击这些按钮以启动所需的转换。
到目前为止,我必须使用.cs文件:MainForm.cs和ConversionForm.cs。
在MainForm.cs中,我已将MainForm声明为static,以赋予ConversionForm访问其方法的权限。
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中,我有一个"转换"应根据用户的输入选择处理转换的按钮。
public void conversionButton_Click(object sender, EventArgs e)
{
if (MainForm.mform.CSVConversionRadio.Checked = true)
{
CSVConversion();
}
if (MainForm.mform.TXTConversionRadio.Checked = true)
{
TXTConversion();
}
}
我遇到的问题是当函数检查单选按钮的状态时,程序返回" null",抛出异常。在对代码进行一些更改之前,即声明静态函数
public static MainForm mform = null;
MainForm.mform.CSVConversionRadio.Checked总是返回状态" false",可能是因为正在实例化新表单(Conversion)并且事件处理程序将其状态重置为默认状态。
所以,这是我的问题:
如何将单选按钮的当前值传递给转换表单,允许转换功能根据用户的选择执行?
一般来说,如何在不创建新实例的情况下从其他表单引用属性,方法和字段,但只指向仍在打开的前一个实例?
答案 0 :(得分:1)
在表单之间共享信息的方法有多种。
我认为一个简单的方法是拥有一个两种形式都知道的中介类。
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
}
}
按下ConversionForm中的按钮时,会设置类型
public void conversionButton_Click(object sender, EventArgs e) {
switch (context.Type) {
case ConversionType.Csv:
CSVConversion();
break;
case ConversionType.Txt:
TXTConversion();
break;
}
}
这也减少了表单之间的依赖关系,导致两者之间的looser coupling。
答案 1 :(得分:0)
扔掉那个静态变量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控件状态的信息
添加这两个公共属性
public bool CSVConversionRequired
{
get { return (this.CSVConversionRadio.Checked); }
}
public bool TXTConversionRequired
{
get { return (this.TXTConversionRadio.Checked); }
}
并将ConversionForm更改为
public void conversionButton_Click(object sender, EventArgs e)
{
if (_currentInstanceMainForm.CSVConversionRequired == true)
CSVConversion();
if (currentInstanceMainForm.TXTConversionRequired == true)
{
TXTConversion();
}
}