доступ к компоненту формы из другого объекта выдает «System.NullReferenceException было необработанным»

#c#

#c#

Вопрос:

Я пытаюсь изменить текстовое поле, принадлежащее Form2, из объекта WCF.

 namespace server2
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private ServiceHost duplex;

        private void Form2_Load(object sender, EventArgs e)     /// once the form loads, create and open a new ServiceEndpoint.
        {
            duplex = new ServiceHost(typeof(ServerClass));
            duplex.AddServiceEndpoint(typeof(IfaceClient2Server), new NetTcpBinding(), "net.tcp://localhost:9080/service");
            duplex.Open();
            this.Text = "SERVER *on-line*";
        }
    }


    class ServerClass : IfaceClient2Server
    {


        IfaceServer2Client callback;

        public ServerClass()
        {
            callback = OperationContext.Current.GetCallbackChannel<IfaceServer2Client>();

        }

        public void StartConnection(string name)
        {
            var myForm = Form.ActiveForm as Form2;
            myForm.textBox1.Text = "Hello world!";  /// <- this one trows “System.NullReferenceException was unhandled”
                                                    /// unless Form2 is selected when this fires.

            callback.Message_Server2Client("Welcome, "   name );
        }


        public void Message_Cleint2Server(string msg)
        {
        }

        public void Message2Client(string msg)
        {
        }

    }




    [ServiceContract(Namespace = "server", CallbackContract = typeof(IfaceServer2Client), SessionMode = SessionMode.Required)]


    public interface IfaceClient2Server           ///// what comes from the client to the server.
    {
        [OperationContract(IsOneWay = true)]
        void StartConnection(string clientName);

        [OperationContract(IsOneWay = true)]
        void Message_Cleint2Server(string msg);
    }


    public interface IfaceServer2Client          ///// what goes from the sertver, to the client.
    {
        [OperationContract(IsOneWay = true)]
        void AcceptConnection();

        [OperationContract(IsOneWay = true)]
        void RejectConnection();

        [OperationContract(IsOneWay = true)]
        void Message_Server2Client(string msg);
    }

}
  

Тем не менее, строка «myForm.TextBox1.Text = «Привет, мир!»;» исключение System.NullReferenceException было необработанным»…

Есть идеи, спасибо!

Комментарии:

1. Вы уверены, что активная форма на самом деле является экземпляром Form2 ? Если нет, то as вернется null .

2. нет, на самом деле это не так! как я должен получить к нему доступ?

3. Нам понадобится гораздо больше информации о том, как настроены ваши формы, чтобы точно узнать, где находится ваш экземпляр «Form2″…

4. Если это не экземпляр Form2, зачем вы обращаетесь к нему? Очевидно, вы ожидаете, что это будет экземпляр Form2 с этим конкретным текстовым полем на нем. Вам нужно сообщить нам на английском языке, что вы хотите сделать.

5. TextBox1 является экземпляром Form2. тем не менее, я обращаюсь к нему не из другого, а из объекта wcf.

Ответ №1:

myForm может быть не того Form2 типа, или оно может не содержать textBox1 поля. Обязательно проверьте наличие null в обоих этих случаях.

Ответ №2:

Как обсуждалось в комментариях к первоначальному вопросу, проблема в том, что вы ссылаетесь на ActiveForm, когда нужная вам форма неактивна. Всякий раз, когда вы пытаетесь выполнить приведение с использованием as ключевого слова, результат будет нулевым, если приведение недопустимо. Поскольку вы получили форму, которая не могла быть преобразована в Form2 (поскольку это была форма другого типа), вы правильно получили исключение нулевой ссылки.

Предполагая, что вы применили правила singleton для Form2 и не играли с именем формы, вы можете получить к ней доступ с помощью приложения.Коллекция OpenForms выглядит следующим образом:

 (Form2)Application.OpenForms["Form2"];
  

В вашем примере кода это может выглядеть следующим образом:

 public void StartConnection(string name)
{
    //var myForm = Form.ActiveForm as Form2;
    var myForm = Application.OpenForms["Form2"] as Form2;
    myForm.textBox1.Text = "Hello world!";  /// <- this one trows “System.NullReferenceException was unhandled”
                                            /// unless Form2 is selected when this fires.

    callback.Message_Server2Client("Welcome, "   name );
}
  

Тем не менее, я не думаю, что я бы передал ответственность за изменение элементов управления формой службе WCF. Я бы гораздо скорее использовал события, запускаемые службой внутри моей формы.

Комментарии:

1. Рад это слышать. Не забудьте рассмотреть мое последнее предложение. ;o)