无法通过具有第三方提供的类的嵌套类型访问外部类型XXX的非静态成员

时间:2015-08-31 01:13:14

标签: c# .net forms callback nested

此问题已在SOF中得到解决。但是,我无法(不够称职)将建议应用于此示例。我得到“无法通过嵌套类型访问外部类型的非静态成员'FixClientTest.Form1'”错误。在这种情况下,嵌套类型是第三方提供的类(在本例中为开源QuickFix / n库)的实例化。我知道源代码并不是真正相关,但我试图避免任何可能让我修改代码并且没有解决问题的知识的建议。我的目标只是根据我从这个库中回调的信息更新表单控件。 (下面的代码只是一个带有2个按钮的简单表单,一个用于设置事件回调,另一个用于阻止它们。)我非常感谢社区可能提出的任何建议。

谢谢。

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using QuickFix;

namespace FixClientTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public class MyQuickFixApp : QuickFix.IApplication
        {    
            public void FromApp(QuickFix.Message msg, SessionID sessionID) { }
            public void OnCreate(SessionID sessionID) { }
            public void OnLogout(SessionID sessionID) 
            {
                Console.WriteLine("Logged out.");
            }
            public void OnLogon(SessionID sessionID) 
            {
                Console.WriteLine("Logged In.");
            }
            public void FromAdmin(QuickFix.Message msg, SessionID sessionID) 
            {
                //logListView.Items.Add(msg.ToString()); <<GENERATES ERROR!

            }
            public void ToAdmin(QuickFix.Message msg, SessionID sessionID) { }
            public void ToApp(QuickFix.Message msg, SessionID sessionID) { }
        }

        public QuickFix.Transport.SocketInitiator _Initiator = null;

        private void connectButton_Click(object sender, EventArgs e)
        {
            string file = "c:/FIX/tradeclientIB.cfg";
            try
            {
                QuickFix.SessionSettings settings = new QuickFix.SessionSettings(file);
                QuickFix.IApplication myApp = new MyQuickFixApp();
                QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
                QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
                _Initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);   
                _Initiator.Start();

            }
            catch (System.Exception err)
            {
                MessageBox.Show(err.ToString());
            }
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            _Initiator.Stop();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您的MyQuickFixApp班级对Form1对象一无所知。

首先,我建议将其移出Form1课程。 然后,我将看看如何以及何时创建MyQuickFixApp对象。我不熟悉QuickFix库,但快速浏览文档表明在按钮消息处理程序中创建它并不是正确的方法。 (在winforms应用程序中,我想你会用Program.Main方法创建它。)

对于实际错误,您需要为MyQuickFixApp对象提供对Form1对象的引用(可能在构造函数中传递它)。

public class MyQuickFixApp : QuickFix.IApplication
{
    private readonly Form1 _form1;
    public MyQuickFixApp(Form1 form)
    {
       _form1 = form;
    }

    public void FromAdmin(QuickFix.Message msg, SessionID sessionID) 
    {
        _form1.logListView.Items.Add(msg.ToString());
    }
}

答案 1 :(得分:0)

在我等待答案时,我又看了一下这个链接提供的答案: Property is inaccessible due to its protection level这次当我再次仔细阅读时,我意识到史蒂夫已经发布了我需要的答案,所以这才是他的答案。我需要使用事件重构这个以捕获表单中的更改并保留封装。它还允许我移动我的类,将表格更新为Form类,但是,它创建了令人恐惧的“跨线程”问题。我已经从其他人那里得到了答案(对不起,没有那个链接)。我在更新表单的事件中添加了行,以将其作为新线程旋转。我以前做过这个,它很好用。如果有人认为这可能是个问题,请告诉我。抱歉,如果我浪费了任何人的时间来查看我的问题,但我想我会分享各种答案,因为它解决了我学习c#/表格后遇到的两个最大的问题。

有一点,不要对这个声明感到困惑:private delegate void AddLogItemDelegate(string msg);它与创建包含AddLogItem函数的线程有关,而不是与事件的创建有关。

由于

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using QuickFix;

namespace FixClientTest
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public QuickFix.Transport.SocketInitiator _Initiator = null;

        private void connectButton_Click(object sender, EventArgs e)
        {
            string file = "c:/FIX/tradeclientIB.cfg";
            try
            {
                QuickFix.SessionSettings settings = new QuickFix.SessionSettings(file);
                QuickFix.IApplication myApp = new MyQuickFixApp();
                QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
                QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
                //QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);
                _Initiator = new QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory);

                MyQuickFixApp.UpdateEvent += new MyQuickFixApp.OnUpdateEvent(AddLogItem);
                _Initiator.Start();

            }
            catch (System.Exception err)
            {
                Console.WriteLine(err.Message);
                Console.WriteLine(err.StackTrace);
                MessageBox.Show(err.ToString());
            }
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            _Initiator.Stop();
        }
        public string stuff;

        private delegate void AddLogItemDelegate(string msg);
        public void AddLogItem(string msg)
        {
            if(this.InvokeRequired)
            {
                this.Invoke(new AddLogItemDelegate(AddLogItem), new object[] { msg });
                return;
            }

            try
            {
                logListView.Items.Add(msg);
            }
            catch(Exception err)
            {
                MessageBox.Show(err.ToString());
            }
        }
    }


    public class MyQuickFixApp : QuickFix.IApplication
    {

        public delegate void OnUpdateEvent(string msg);
        public static event OnUpdateEvent UpdateEvent;

        public void FromApp(QuickFix.Message msg, SessionID sessionID) { }
        public void OnCreate(SessionID sessionID) { }
        public void OnLogout(SessionID sessionID)
        {
            Console.WriteLine("Logged out.");
        }
        public void OnLogon(SessionID sessionID)
        {
            UpdateEvent("STUFF!!");
            Console.WriteLine("Logged In.");
        }
        public void FromAdmin(QuickFix.Message msg, SessionID sessionID)
        {

        }
        public void ToAdmin(QuickFix.Message msg, SessionID sessionID) { }
        public void ToApp(QuickFix.Message msg, SessionID sessionID) { }
    }


}