Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C#] В одном классе вызвать метод другого, нестатический метод 
V
    Опции темы
Rockie
Дата 20.9.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



Здравствуйте!

Как вызвать в одном классе нестатический метод другого класса? Вот пример.

Код
namespace Binary
{

    // один класс
    class MyTextBox : TextBox
    {   
        // перехватываю PASTE на textBox-е, но вопрос не про это
        const int WM_PASTE = 0x0302;

        protected override void WndProc(ref Message m)
        {
           // вот здесь мне нужно вызвать нестатический метод 
           // MethodFromForm1 из класса Form1
           
            base.WndProc(ref m);
        }
    }

    
    // другой класс
    public partial class Form1 : Form
    {
        // нестатический метод 
        public void MethodFromForm1
        {
  
        }

    }
}


Сразу скажу что тут смотрел.
При объявлении метода MethodFromForm1 с модификатором const я во-первых ловлю кучу ошибок в этих функциях
Цитата
Static member '..MethodFromForm1' cannot be accessed with an instance reference; qualify it with a type name instead  ...\Form1.cs

А во-вторых я не хочу открывать их полностью. Также нашел такой вариант как

Код
class MyTextBox : TextBox
    {   
        // перехватываю PASTE на textBox-е, но вопрос не про это
        const int WM_PASTE = 0x0302;

        protected override void WndProc(ref Message m)
        {
           // вот здесь мне нужно вызвать нестатический метод 
           // MethodFromForm1 из класса Form1
        Form1 f = new Form1();
            f.MethodFromForm1();
           
            base.WndProc(ref m);
        }
    }

Вродже бы выход из положения, но у меня на даном этапе не работает smile) , а во-вторых мне очень накладно каждый раз создавать экземпляр формы в этом маааа-леньком методе. 

Ну и в конце концов я здесь вычитал  , что можно при инициализации myTextBox передать ему ссылку на Form1. Вот скажите пожалуйста как это сделать. Либо если у вас есть  - какие-то еще способы.

Это сообщение отредактировал(а) Rockie - 20.9.2007, 17:56


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
yar
Дата 20.9.2007, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 8.9.2007
Где: Одесса, Украина

Репутация: 2
Всего: 8



В этом конкретном случае можно воспользоваться свойсвом контрола TopLevelControl, таким образом получив ссылку на форму.

Код

 protected override void WndProc(ref Message m)
{
         // ...
          (this.TopLevelControl as Form1).MethodFromForm1();
   
            base.WndProc(ref m);
}

--------------------
Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы мировую цивилизацию.Джеральд Вайнберг
PM MAIL WWW   Вверх
Alek86
Дата 20.9.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 1
Всего: 25



интересно узнать, что делает функция MethodFromForm1().
Если ничего не использует из переменных-членов Form1, то смело можно делать ее статической.
Если же она использует переменные-члены Form1, то чего ты добьешься если создашь временный объект и выполнишь для него эту функцию?



Цитата(Rockie @  20.9.2007,  17:54 Найти цитируемый пост)
при инициализации myTextBox передать ему ссылку на Form1. Вот скажите пожалуйста как это сделать.


Код

class MyTextBox : TextBox
    {   
        const int WM_PASTE = 0x0302;
        Form1 m_Form1;

        public MyTextBox(Form1 vForm1)  {
               m_Form1 = vForm1;
        }

        protected override void WndProc(ref Message m)
        {
           // вот здесь мне нужно вызвать нестатический метод 
           // MethodFromForm1 из класса Form1
            m_Form1.MethodFromForm1();
           
            base.WndProc(ref m);
        }
    }




но перед тем, как реализовывать, подумай, для чего тебе вообще такое нужно?


--------------------
user posted image    user posted image
PM MAIL   Вверх
Experimenter
Дата 20.9.2007, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 4
Всего: 17



Код

static void Main()
        {
            Form1 f1 = new Form1();
            Application.Run(new MyTextBox(ref f1));
        }

public MyTextBox(ref Form1 frm1) {}


не прокатывает так?

Это сообщение отредактировал(а) Experimenter - 20.9.2007, 19:04


--------------------
public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){
    if(zlo1 < zlo2) return zlo1;
    else if(zlo1 > zlo2) return zlo2;
    else throw new Exception("Kill yourself by the wall"); }
PM WWW ICQ   Вверх
matkir
Дата 20.9.2007, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 14.9.2007
Где: самара

Репутация: нет
Всего: нет



вот как можно сделать:
Код

class MyTextBox: System.Windows.Forms.TextBox
    {
        Form1 f;
      

        public MyTextBox()
        {
           
                       
        }
        public Form1 set_form
        {
            set
            {
                f=value;
            }
        }
        void fun()
        {
            f.MethodFromForm1();
        }
        
    }



основное окно
Код

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

        private void button1_Click(object sender, EventArgs e)
        {
            MyTextBox Cmy=new  MyTextBox();
            Cmy.set_form=this;
        }


        public void MethodFromForm1()
        {


        }

PM MAIL ICQ GTalk   Вверх
Experimenter
Дата 20.9.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 4
Всего: 17



matkir жжот, про свойства-то забыли? так красивее выглядит...


--------------------
public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){
    if(zlo1 < zlo2) return zlo1;
    else if(zlo1 > zlo2) return zlo2;
    else throw new Exception("Kill yourself by the wall"); }
PM WWW ICQ   Вверх
tol05
Дата 21.9.2007, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



Цитата(yar @  20.9.2007,  18:25 Найти цитируемый пост)
В этом конкретном случае можно воспользоваться свойсвом контрола TopLevelControl, таким образом получив ссылку на форму.

yar, нет нельзя. Если контрол будет не на форме, а на панели или в другом контейнере, что ты получишь?

Цитата(Alek86 @  20.9.2007,  18:36 Найти цитируемый пост)
Если ничего не использует из переменных-членов Form1, то смело можно делать ее статической.

статики - это зло....

Цитата(Rockie @  20.9.2007,  17:54 Найти цитируемый пост)
Ну и в конце концов я здесь вычитал  , что можно при инициализации myTextBox передать ему ссылку на Form1. Вот скажите пожалуйста как это сделать. Либо если у вас есть  - какие-то еще способы.

Да можно. ИМХО - достаточно эффективный и простой способ. 
Alek86, привел пример передачи ссылки на форму при создании контрола. 

Цитата(Alek86 @  20.9.2007,  18:36 Найти цитируемый пост)
но перед тем, как реализовывать, подумай, для чего тебе вообще такое нужно?

Я могу сказать, для чего это мне может быть нужно smile для работы с событиями и свойствами формы например.
Если у меня будет 100 контролов, который из  которых должен реагировать на 10-20 событий формы, то я НИКОГДА не буду привязывать обработчики контрола к событиям формы руками smile
Контрол имеет свое постоянное поведение, зависящее от состояния и поведения формы. Все это реализуется через закрытый интерфейс контрола, именно таким способом.


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
yar
Дата 21.9.2007, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 8.9.2007
Где: Одесса, Украина

Репутация: 2
Всего: 8



Цитата(tol05 @  21.9.2007,  23:01 Найти цитируемый пост)
yar, нет нельзя. Если контрол будет не на форме, а на панели или в другом контейнере, что ты получишь?


Получу ссылку на форму:
Цитата

Gets the parent control that is not parented by another Windows Forms control. Typically, this is the outermost Form that the control is contained in.
(Источник)



Это сообщение отредактировал(а) yar - 21.9.2007, 23:12
--------------------
Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы мировую цивилизацию.Джеральд Вайнберг
PM MAIL WWW   Вверх
tol05
Дата 22.9.2007, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



да, признаю, что когда писал, не перечитал мануал по этому свойству. Похоже вернется именно форма...

Но все равно не стал бы использовать TopLevelControl. И не только из-за духа противоречия (хотя и он присутствует  smile ). 
Любая конкретика ИМХО всегда вредна. Это враг дальнейшего сопровождения, масштабируемости, версионирования...

Пример: взаимодействие дочерних форм MDI-приложения с контролами главной формы...
Как при использовании TopLevelControl контрол сможет получить ссылку на форму, его НЕ СОДЕРЖАЩУЮ?

"Похоже вернется именно форма..." Но какая?



--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
yar
Дата 22.9.2007, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 8.9.2007
Где: Одесса, Украина

Репутация: 2
Всего: 8



tol05
Так или иначе, для того, чтобы выбрать лучший вариант, необходимо иметь хотя бы несколько альтернатив smile. Для не-mdi интерфейса TopLevelControl корректно работает.

А ещё есть Control.FindForm(), он работает правильно и в MDI-интерфейсе, возвращая ссылку не на MDI-контейнер, как TopLevelControl, а непосредственно на форму, на которой содержится наш контрол. Так что, кажется мне, передача контролу в конструкторе ссылки на содержащую его форму является избыточной.
Поэтому, что использовать, зависит от того, ссылку на какую форму мы хотим получить smile



Это сообщение отредактировал(а) yar - 22.9.2007, 13:52
--------------------
Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы мировую цивилизацию.Джеральд Вайнберг
PM MAIL WWW   Вверх
Alek86
Дата 22.9.2007, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 1
Всего: 25



Цитата(tol05 @  21.9.2007,  23:01 Найти цитируемый пост)
Цитата(Alek86 @  20.9.2007,  18:36 )Если ничего не использует из переменных-членов Form1, то смело можно делать ее статической.статики - это зло....


ну, иногда это зло необходимое. к примеру Format у String (так, кажется). больше ведь никуда не приткнешь.


Цитата(tol05 @  21.9.2007,  23:01 Найти цитируемый пост)
Цитата(Alek86 @  20.9.2007,  18:36 )но перед тем, как реализовывать, подумай, для чего тебе вообще такое нужно?
Я могу сказать, для чего это мне может быть нужно  для работы с событиями и свойствами формы например.Если у меня будет 100 контролов, который из  которых должен реагировать на 10-20 событий формы, то я НИКОГДА не буду привязывать обработчики контрола к событиям формы руками Контрол имеет свое постоянное поведение, зависящее от состояния и поведения формы. Все это реализуется через закрытый интерфейс контрола, именно таким способом.


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

Цитата(tol05 @  22.9.2007,  12:48 Найти цитируемый пост)
Любая конкретика ИМХО всегда вредна. Это враг дальнейшего сопровождения, масштабируемости, версионирования...



Это сообщение отредактировал(а) Alek86 - 22.9.2007, 13:54


--------------------
user posted image    user posted image
PM MAIL   Вверх
tol05
Дата 22.9.2007, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



Цитата(Alek86 @  22.9.2007,  13:53 Найти цитируемый пост)
ну, иногда это зло необходимое. к примеру Format у String (так, кажется). больше ведь никуда не приткнешь.

неудачный пример. При каждой манипуляции со строкой создается новая строка, это всем известно. Как же можно вызывать экземплярный метод у объекта, который уже при выполнении этого метода должен стать мусором? Т.е. сам себя сделать мусором. Вот поэтому и статические методы....

Цитата(Alek86 @  22.9.2007,  13:53 Найти цитируемый пост)
я в шарпе не очень опытен, можно поподробнее? не лучше бы было подписаться на события в таком случае? как раз из-за того, что:
Цитата(tol05 @  22.9.2007,  12:48)
Любая конкретика ИМХО всегда вредна. Это враг дальнейшего сопровождения, масштабируемости, версионирования...

Ты не понял.

Я имел в виду следующее:
при разработке контрола необходимо определить его поведение и состояние. При определении поведения разрабатывается как открытый интерфейс, так и закрытый. 
Часть поведенческих функций зависит от конкретной ситуации при использовании контрола. Это выносится в открытый интерфейс и клиент, использующий контрол в своем ПО, сам настраивает поведение контрола (через инициализацию свойств, привязку обработчиков к событиям и т.д.)
Но есть определенная часть поведения контрола, определенная один раз и навсегда разработчиком самого контрола (например, фокус на кнопке прорисовывается пунктиром, в текстбоксе - поле ввода меняет цвет, в форме - подсвечивается заголовок...) Вот это поведение тоже надо программировать и программировать в закрытом интерфейсе контрола. Но текстбокс, к примеру, должен знать когда ему поменять цвет поля ввода, а кнопка должна знать. когда ей нарисовать на себе пунктир. Т.е. контрол должен подписаться на внешнее событие (сообщение, это неважно), и быть готовым его принять и обработать. 
Но как это сделать? Я когда-то писал в лог (надо было smile) сообщения, получаемые кнопкой. Их было около сотни. Думаю, это был не предел. Не заставлять же программиста, вводящего кнопку на форму, подписываться вручную на все эти сообщения? Поэтому кнопка, при своей инициализации, при своем добавлении в родительсктй контейнер сама подписывается на определенные сообщения, это заложено в ней. 
Заканчиваю. Поэтому я и говорил, что передавая ссылку на форму в контрол мы обеспечиваем контрол всем необходимым и он может сам, внутри себя подписаться на все, что ему нужно. Этим мы убиваем двух зайцев: 
1. избавляем программиста от ошибок, когда он в 20 контролах подписался на какое-то событие формы, а в 21 - забыл, или не на то подписался. К тому же, программисту меньше кода писать (это любят называть повторно-используемый код).
2. Обеспечиваем масштабируемость приложения, когда разработчик разработал новую версию контрола, положил его в dll и рассылает патч к своему старому приложению, или плагин. При этом НЕ НУЖНО перекомпилировать все приложение у клиентов всего мира, из-за того, что в новой версии контрол должен еще на пару событий подписаться...
Старый контрол получал ссылку на форму и новый получает, а что они с этой ссылкой делают - это их внутреннее дело, не влияющее на работу формы и старого кода.

Вот такое мое личное мнение smile

А по поводу конкретики - развиваю мысль о MDI. Создано 10 дочерних форм, они все - одного класса. Контрол один и находится на родительской форме. Это label. Мне нужно сделать, чтобы при создании дочерней формы label отображал надпись с информацией о форме. Я не хочу, чтобы клиент разрабатывал этот код и писал что ему вздумывается, я сам напишу, только дай мне ссылку на создаваемую форму. Как я ее получу через TopLevelControl? или черезControl.FindForm()?

Все, закончил, извините за длинный пост.

Это сообщение отредактировал(а) tol05 - 22.9.2007, 21:51


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
yar
Дата 22.9.2007, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 8.9.2007
Где: Одесса, Украина

Репутация: 2
Всего: 8



tol05
Хороший пост, спасибо smile

Цитата

А по поводу конкретики - развиваю мысль о MDI. Создано 10 дочерних форм, они все - одного класса. Контрол один и находится на родительской форме. Это label. Мне нужно сделать, чтобы при создании дочерней формы label отображал надпись с информацией о форме. Я не хочу, чтобы клиент разрабатывал этот код и писал что ему вздумывается, я сам напишу, только дай мне ссылку на создаваемую форму. Как я ее получу через TopLevelControl? или черезControl.FindForm()?

Но я говорил лишь о том, что если нам нужно получить ссылку именно на родительскую форму для данного контрола, то для этого уже предусмотрен механизм в виде FindForm(), и не нужно делать это самостоятельно. Если же нам нужна ссылка на какую-либо другую форму, как в этом примере, конечно, удобнее всего передавать её нашему label при создании. smile

--------------------
Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы мировую цивилизацию.Джеральд Вайнберг
PM MAIL WWW   Вверх
Rockie
Дата 23.9.2007, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



У меня на форме группа контролов, приемущественно текстбоксы. Мне нужно вместо стандартного paste выполнять ряд своих дествий, причем при вставке в один из текстобксов он взаимодействует с другими, поэтому я отнаследовал свой класс текстбокса с чуть измененным функционалом и мне нужно было достучаться до других на форме. 

Впринцыпе первый предложенный вариант с TopLevelControl меня уже спас, но рассмотрю и все остальные варианты. 

Большое спасибо всем за информативные ответы! =)


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0975 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.