Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 参见RadioButton_checked从另一个表单更改的值_C#_Winforms_Radio Button - Fatal编程技术网

C# 参见RadioButton_checked从另一个表单更改的值

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

我正在编写一个小程序,可以处理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中,我有一个“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关闭之前)