Как подписать Label на событие класса?

192
16 ноября 2021, 18:10

Пишу приложение, для которого надо выводить информацию из объекта созданного мною класса в Label.Text. Создал тестовый проект: форма, на ней Label1 и Button1. (Visual Studio 2019 - Windows Forms App - Net Framework). За основу взял статью "События C# по-человечески". Хочу запустить счетчик по нажатию на Button1 и вывести значение счетчика в Label1.Text с помощью события. Код генерации события студия одобрила. А вот как написать обработчик события, который выводит в Label1.Text значение счетчика, и как подписать его на событие onCount() - даже не могу представить. Подскажите, пожалуйста, что делать? Или хотя бы правильное направление поисков.

Код тестового проекта:

using System.Windows.Forms;
namespace WindowsFormsApp_NetFrameWork_Test
{
    public partial class Form1 : Form
    {
        ClassCounter MyCounter = new ClassCounter();
        public Form1()
        {
            InitializeComponent();
            MyCounter.onCount += ???
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        MyCounter.Count();
    }

    class ClassCounter
    {
        public delegate void MethodContainer(int k);
        public event MethodContainer onCount;
        public void Count()
        {
            for (int i = 0; i < 100; i++)
            {
                if (i == 71)
                {
                    onCount(i);
                }
            }
        }    
    }
    class ??? Как-то так представляю себе обработчик события onCount
    {
        public void ChangeMyLabel(int i)
        {
            this.Text = "Подсчитано: " + i.ToString();
        }
    }
}
Answer 1
...
MyCounter.onCount += onCountHandler;
...
private void onCountHandler("то, что вы хотите передать, например int i")
{
     Label1.Text = Convert.ToString(i);
}

Вы подписываете на событие метод, которые совпадает по сигнатуре с вызывающем событие. Ключевые слова для поиска: события и их обработка C#, делегаты

Обращение к методу(например onCountHandler) на самом деле в полной форме выглядит как this.onCountHandler, просто this опускается для элегантности. Вот как на самом деле в полной форме выглядит ваш кусок кода.

public Form1()
{
    this.InitializeComponent();
    this.MyCounter.onCount += this.onCountHandler;
}

Поэтому если вы вынесите метод вне класса, то если у вас не будет конкретного экземпляра в области видимости, вы и не сможете к обратится к функции. Смотрите

class Человек
{
  public void Зайти()
  {
      СказатьПривет();
      // Эквивалент this.СказатьПривет();
      // Надо записаться в журнале, что я пришел
      Писать();
      // Напомню, что эквивалент this.Писать(); Но вы же не объявляли в рамках данного класса такого метода, поэтому и вызвать не можете. 
      // Ошибка, непонятно у кого вызывать этот метод. У меня такого метода нет, а ссылка на того, кто может это сделать нет. Исправляем
      Ручка ТекущаяРучка = new Ручка();
      ТекущаяРучка.Писать();
      //Вы создали экзмепляр класса и вызвали метод писать у этого экземпляра. Теперь все верно.
      // О логике я не думал в примере, очевидно ручка сами не пишет, ей пишет человек. Но суть должны быть понятна.
  }
  public void Уйти()
  {
      ...
  }
  public void СказатьПривет()
  {
      Зайти();
      // Эквивалент this.Зайти();
  }
  public void СказатьПока()
  {
      ...
  }
}
class Ручка
{
   public void Писать()
   {
   }
 }

Как узнать, кому принадлежит метод, а кому нет? По скобочками. Это называется областью видимости. Все, что внутри скобочек класса - принадлежит классу и видно только внутри класса(доступно по ключевому слову this), остальное находится вне класса.

Почитайте про "область видимости" внимательнее(прям загуглите),например тут https://metanit.com/sharp/tutorial/2.18.php

Answer 2

Спасибо Arantler! Заработало. К сожалению, таким, как я, новичкам подобные ответы мало чем помогают. Кроме того, ЧТО кодить, надо понимать еще ГДЕ. Для таких, как я, выкладываю заработавший код.

using System.Windows.Forms;
namespace WindowsFormsApp_NetFrameWork_Test
{
    public partial class Form1 : Form
    {
        ClassCounter MyCounter = new ClassCounter();
        public Form1()
        {
            InitializeComponent();
            MyCounter.onCount += onCountHandler;
        }
    }
    public void onCountHandler(int i)
    {
        label1.Text = Convert.ToString(i);
    }
    private void button1_Click(object sender, EventArgs e)
    {
        MyCounter.Count();
    }

    class ClassCounter
    {
        public delegate void MethodContainer(int k);
        public event MethodContainer onCount;
        public void Count()
        {
            for (int i = 0; i < 100; i++)
            {
                if (i == 71)
                {
                    onCount(i);
                }
            }
        }    
    }
}
READ ALSO
C# WFP MVVM Получить доступ из VM к UIElement

C# WFP MVVM Получить доступ из VM к UIElement

Есть Окошко с VM, есть кнопка с командой,(при нажатии на кнопку должен происходить парсинг объекта, передаваемого через CommandParametr и Записывать...

162
Использовать Select в async

Использовать Select в async

если не сложно тыкните меня в ошибку, не могу понять как использовать селект в асинхронном методе

230
Перегрузка оператора при наследовании

Перегрузка оператора при наследовании

Можно как-нибудь наследовать перегрузку операторов? Сейчас я повторно дублирую код, например как в нижеприведенном коде

213