Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Читаю Петцольда, возникают вопросы...


Автор: elvad 21.4.2008, 15:55
Здравствуйте! Учусь по Петцольду - Программирование для Microsoft Windows на С#. Знаком только с основами Си. Дошёл до Главы2. "Обработка события Paint". Появились непонятные моменты. (Я в код добавил свои комментарии. И проект создавал пустой). Вот программа из книги:
Код

using System;
using System.Windows.Forms;
using System.Drawing;

class Simple
{
    public static void Main()
    {
        Form form1 = new Form();
        form1.Paint += new PaintEventHandler(form1_Paint);
        Application.Run(form1);
    }
    
    static void form1_Paint(object sender, PaintEventArgs pea)
    {
        Graphics g = pea.Graphics;
        g.Clear(Color.Chocolate);
        Console.WriteLine("Paint event");//не запускается, срабатывает только MessageBox.Show()
    }
 }


По этому коду такие вопросы:
1) Правильно ли я  понимаю, что при создании обработчика события form1_Paint в параметрах указано, что создаются объект sender из класса object и объект pea из класса  PaintEventArgs)
2) Можно ли сравнить создание обработчика событий из делегата, с созданием объекта из класса.
3) Я пытаюсь включить в обработчик событий form1_Paint изменение названия Form1:
form1.Text = "New name"; 
но возникает ошибка "name form1 does not exist in current context"

Автор: Kefir 21.4.2008, 16:58
1) не совсем. обработчик события - это обычная функция. object sender, PaintEventArgs pea - это её аргументы. они, конечно, где-то создаются, но не в самом обработчике. проще говоря, где-то в классе формы есть строка this.Paint(this, new PaintEventArgs(...)).
2) очень отдалённо, но можно.
3) значит нет такой переменной. а нет потому, что ты её объявил в методе Main, то есть её звать можно только там. Тут есть два варианта. Первый вариант - это брать форму из аргумента sender (в sender хранится обьект, который вызвал Paint). то есть ты можешь написать
Код

(sender as Form1).Text = "New name";

Или объяви form1 как член класса Simple
Код
using System;
using System.Windows.Forms;
using System.Drawing;
class Simple
{
    Form form1 = new Form();
    public static void Main()
    {
        form1.Paint += new PaintEventHandler(form1_Paint);
        Application.Run(form1);
    }
    
    static void form1_Paint(object sender, PaintEventArgs pea)
    {
        Graphics g = pea.Graphics;
        g.Clear(Color.Chocolate);
        Console.WriteLine("Paint event");// открой консоль в студии - там он тебе это покажет при дебаге
        form1.Text = "New name";
    }
 }

Автор: WarHog 22.4.2008, 07:43
Цитата(elvad @ 21.4.2008,  15:55)
Код

Console.WriteLine("Paint event");//не запускается, срабатывает только MessageBox.Show()

Не запускается, очевидно, из-за того, что выбран тип приложения Windows, а не Console (опциями компилятора, если компилишь из строки csc или в Project Properties->Application->Output type)

Автор: Kefir 22.4.2008, 08:19
WarHog, ещё раз говорю - в консоли студии при дебаге будет этот вывод. или же если запустить программу из консоли - тоже будет работать.

Добавлено через 1 минуту и 47 секунд
и тип приложения к этому не имеет никакого отношения. просто если вы пишете консольное приложения - вы его запускаете в консоли и видите вывод. а если винформсы, то консоли вы не видите («Ты суслика видишь? — Нет. — И я нет. А он есть!»). вот так.  smile 

Автор: thomas 22.4.2008, 09:02
WarHog, 
Цитата

 а если винформсы, то консоли вы не видите 

= output
 smile 

Автор: WarHog 22.4.2008, 09:15
Kefir, это понятно smile
Я и имел в виду, что если выбрать winforms, то консоли не будет видно, просто не так выразился  smile 

Автор: elvad 22.4.2008, 09:32
Kefir, 
Спасибо за разъяснение! Я использую Visual C# 2008 Express.
Первый вариант получился, когда я написал (sender as Form).Text = "New name"; 
А вот на второй выдаёт ошибку An object reference is required for the non-static field, method, or property 'Simple.form1'

Ещё внутри функции form1_Paint есть строки:
Graphics g = pea.Graphics;
g.Clear(Color.Chocolate);
Петцольд пишет, что PaintEventArgs содержит свойство Graphics, которое включает в себя экземпляр класса System.Drawing.Graphics (пока не могу понять, как свойство может включать в себя целый объект smile ).
А g это объект типа Graphics. Какой смысл записывать две строки кода и создавать g, когда я написал одну строку 
pea.Graphics.Clear(Color.Chocolate); 
и приложение запустилось с тем же эффектом?

Автор: Kefir 22.4.2008, 10:27
Цитата(elvad @  22.4.2008,  09:32 Найти цитируемый пост)
А вот на второй выдаёт ошибку An object reference is required for the non-static field, method, or property 'Simple.form1'

покажи что у тебя написано, такое впечатление что ты пытаешься использовать не static мембера как будто это static (например вместо form1.Text = "" написано Form.Text = "").


Цитата(elvad @  22.4.2008,  09:32 Найти цитируемый пост)
А g это объект типа Graphics. Какой смысл записывать две строки кода и создавать g, когда я написал одну строку 
pea.Graphics.Clear(Color.Chocolate); 
и приложение запустилось с тем же эффектом?

ну тут два смысла может быть:
1. показательный (показать какой именно класс у pea.Graphics)
2. часто так делается для удобства, чтобы каждый раз не писать pea.Graphics, а использовать просто g.

Автор: elvad 22.4.2008, 12:05
Да собственно, тот код который ты предложил в самом начале, я вставляю в файл проекта и жму F5. Появляется эта ошибка.

Автор: Kefir 22.4.2008, 12:16
тогда проект запости

Автор: source777 22.4.2008, 15:31
elvad, возьми себе что-нить попроще Петцольда почитать, Шилдта например. А то такое ощущение, что ты не понимаешь то, что читаешь...

Автор: elvad 23.4.2008, 09:37
Kefir, 
Вот проект http://slil.ru/25720197 

Source777, 
Может ты и прав, у Петцольда по консоли немного примеров, хотя он в предисловии пишет, что для чтения небходимо знание С. (наверное очень хорошее знание   smile ).
Посмотрю Шилдта...

Автор: Kefir 23.4.2008, 13:05
чёрт, вот я и постарел. совсем запутался. в общем дело то в том, что так ты пытаешься вызвать член класса из статичных методов. у тебя они оба - статик. то биш некуда обращаться, так как обьекта Simple как такового нет. соответственно, тебе надо написать ещё один класс, который будем заниматься всеми делами, а в мэйне просто писать:
Код

    public static void Main()
    {
        MyMightyApplication mma = new MyMightyApplication();
    }


А вообще по хорошему надо делать главную форму, в которой делать все дела. То есть примерно так:
Код

    public class MyMainForm : Form
    {
        // здесь вся твоя логика и тому подобное
    }
    public static void Main()
    {
        MyMainForm mmf = new MyMainForm ();
        Application.Run(mmf);
    }

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)