0

我正在编写一个小程序,它应该处理 CSV 和 XML 之间以及从 XML 到 TXT 的转换。在主窗体中,我插入了两个单选按钮,用户将单击它们以开始所需的转换。

到目前为止,我必须使用 .cs 文件:MainForm.cs 和 ConversionForm.cs。

在 MainForm.cs 中,我已将 MainForm 声明为静态,以允许 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”状态,可能是因为正在实例化新表单(转换)并且事件处理程序将其状态重置为默认值。

所以,这是我的问题:

  1. 如何将单选按钮的当前值传递给转换表单,从而允许根据用户的选择执行转换功能?

  2. 一般来说,我如何从另一个表单引用属性、方法和字段,而不创建新实例,而只指向仍然打开的前一个实例?

4

2 回答 2

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;
    }
}

这也减少了表单之间的依赖关系,导致两者之间的耦合更松散

于 2013-03-22T22:02:18.000 回答
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 控件状态的信息

在 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();
    }
}
于 2013-03-22T21:55:09.707 回答