Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: проблема со static - функцией  (Прочитано 8516 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 24-04-2007 17:29 » 

Господа,

я что-то тут совсем запуталась...  Краснею

Есть класс:
Код:
public class BufReportSettingsGrid : System.Windows.Forms.Form
{
           private DataTable m_BufReportTable;
           // и т.д. - обычные переменные класса


          private void SetGridColStyles()
          {
               // ...
               m_BufReportTable.ColumnChanging += new
                           DataColumnChangeEventHandler( Column_Changing );
          }

  protected static void OnRowChanged(object sender,
                         DataRowChangeEventArgs args)
  {
                :mad:         
              // и вот тут и начинается кино - мне надо вызвать совершенно нормальные (не static) функции моего класса, использовать опять же нормальные переменные класса. При компиляции это сразу же приводит к ошибке...
          }


Итого - тупой вопрос: как выкрутиться из этой ситуации в C#?
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #1 : 24-04-2007 17:36 » 

ой, пардон, не весь текст ... Краснею

В мфц я бы заслала из этой функции WM_USER_DO_SOMETHING и т.о. весь исполняемый код стоял бы в нормальной функции.

А вот как это сделать в C#? Может, использовать события / делегаты? Я просто с C# не работала, посему и вопросы тупые. Здесь была моя ладья...
Записан

холоднокровней, Маня, Ви не на работе
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 24-04-2007 18:04 » 

Malaja, дык... просто так не вызовешь... либо указатель на экземпляр класса надо, либо создать временный экземпляр внутри статик-процедуры... Я так понимаю.

---
ёпперный театр, всё время забываю, что там нету указютелей ) Тогда не знаю
« Последнее редактирование: 24-04-2007 18:20 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 24-04-2007 18:37 » 

Malaja, а "object sender" никак задействовать нельзя? В C# нет подобия dynamic_cast ?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 24-04-2007 18:50 » 

объект sender как раз ссылка на объект, который инициировал событие. Т.е. если ты вежаешь обработчик нажатия на кнопку, то sender будет указывать на эту кнопку. Короче через sender работай.
Записан

ещё один вопрос ...
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-04-2007 18:55 » 

Есть там типа dynamic_cast, правильно будет делать так
Код:
if (obj is string)
{
}

Или можно использоват ключевое слово as. Но в данном случае is удобнее. Вот красноречивый пример для as
Код:
// cs_keyword_as.cs
// The as operator.
using System;
class Class1
{
}

class Class2
{
}

class MainClass
{
    static void Main()
    {
        object[] objArray = new object[6];
        objArray[0] = new Class1();
        objArray[1] = new Class2();
        objArray[2] = "hello";
        objArray[3] = 123;
        objArray[4] = 123.4;
        objArray[5] = null;

        for (int i = 0; i < objArray.Length; ++i)
        {
            string s = objArray[i] as string;
            Console.Write("{0}:", i);
            if (s != null)
            {
                Console.WriteLine("'" + s + "'");
            }
            else
            {
                Console.WriteLine("not a string");
            }
        }
    }
}


0:not a string
1:not a string
2:'hello'
3:not a string
4:not a string
5:not a string

Перекладывая на код Мalaja получим

Код:
protected static void OnRowChanged(object sender,
                         DataRowChangeEventArgs args)
{
     if(sender is BufReportSettingsGrid )
     {
      ///Ваш код
     }
         
}

« Последнее редактирование: 24-04-2007 18:58 от nikedeforest » Записан

ещё один вопрос ...
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 24-04-2007 19:36 » 

А если честно не понял философию, почему мемберная ф-я, которая явно связана с объектом (подозреваю с гридом) должна быть статиком? Обычно это делается для вызова ф-ции без создания объекта. Например подсчитать чё-нить, или распарсить. Но если ф-я называется OnRowChanged - те реакция на изменение строки, то как её можно вызывать, например без отсутствия оной?

Тем паче, что она protected.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 24-04-2007 19:44 » 

Malaja, а удали как оттуда этот static нафик )
Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 24-04-2007 20:50 » 

ДА, ошибка в проектировании напрашивается первой статьей. ПРосто как бы разработчику виднее Улыбаюсь, мы ж всей картины не знаем. А вопрос был четкий Улыбаюсь, подразумевающий четкий ответ
Записан

ещё один вопрос ...
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #9 : 25-04-2007 08:41 » 

Во-первых, всем огромное спасибо!
Ща буду с примерчиком разбираться (я такие операторы не знаю, почитать надо).

Джон, если б я знала, какого хрена оно  static, было бы легче...  Не понял Здесь была моя ладья...
Наверное, я была изначально неправа - не описала ситуацию. Исправляюсь:
на форме есть DataGrid - элемент, в котором есть 2 столбца с инфой (с базами данных это совсем не связано, просто для удобства показа и редактирования данных нанчальство захотело иметь грид - они большие, им видней Ага ). при этом первый столбец - только как инфа, а второй - собственно данные, которые надо менять.
Вот тут и наступил финиш - оказалось, что в этом элементе в си-шарп отсутствует специальный обработчик события типа OnCurrentCellChanging (я не помню, как его зовут в мфц). Значит, надо химичить, но корректно Ага
После всех анализов ситуации (а не моей крови Ага ) я нашла следующее - т.к. грид содержит обьекты типа DataRow и DataColumn, то можно использовать их события, которые возникают при изменении содержимого ячейки (мне надо постоянно контролировать ввод - только числа и только от 0 до 100).
Пример я взяла из МСДНа - там сделано именно так, т.е. они описывают это событие как static. Меня это так же удивило, как и тебя, причем именно по такой же причине, посему я взяла и убрала static нафиг... И тут же получила по башке при выполнении программы...
Итого - напросился вывод о том, что описание функции надо оставить как есть, а бороться с тем, чтобы обойти последствия применения статического метода Ага

Возможно, есть еще какие-то другие способы определить, когда происходит ввод в ячейке и когда он закончен, но я пока его, к сожалению, не нашла.
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #10 : 25-04-2007 09:20 » 

Люди,

опять караул - идея была классная и все скомпилировалось, но потом оказалось, что sender = DataTable, а не грид... А сама таблица не имеет никакой инфы о том, с каким элементом она связана, т.е. невозможно из sender-а получить доступ к обьектам класса формы...
И шо еще можно предпринять?
Записан

холоднокровней, Маня, Ви не на работе
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #11 : 25-04-2007 10:50 » 

Malaja, Я что то не понял совсем что нужно. Давай плизз сначала и по пунктам что есть, что надо, и в какой момент надо что то сделать. Желательно с примерами кода. Будем разбираться.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #12 : 25-04-2007 19:04 » 

Так, тогда еще раз и по порядку Ага

1) есть форма, на которой сидит грид типа DataGrid
2) грид имеет 2 столбца - один readonly (только как инфа), а второй - собственно данные, которые надо менять - это проценты распределения памяти между буферами устройства.
3) Данные должны быть: только числа и только от 0 до 100. Поэтому мне надо постоянно контролировать ввод. Т.е. после каждого введенного символа его надо анализировать - если он не подходит(т.е. не лежит в пределах 0 - 9), то убрать его и оставит предыдущее значение.
После того, как ввод закончен, надо проверить, чтобы число лежало в пределах 0 - 100 и кроме того, посчитать общую сумму чисел и если она больше 100, то заставить клиента подумать и поменять данные Ага
3) в мфц для этого было какое-то виндоус-событие типа ChangedCurCell / ChangingCurCell. В си-шарп же такого нет...
4) т.к. грид содержит обьект типа DataTable (а тот, в свою очередь, DataRow и DataColumn), то можно использовать его события, которые возникают при изменении содержимого ячейки.
5) Пример я взяла из МСДНа - там сделано именно так, т.е. они описывают это событие как static. При попытке убрать его на фиг возникает ошибка в процессе выполнения программы.
6) Сама проблема - мне надо в этой функции использовать обычные переменные моего класса, описывающего форму, причем эти переменные конечно же не static! Результат - компилятор, естественно, орет и посылает подальше (и таки прав ведь)! Ага
В мфц я бы заслала из этой функции WM_USER_DO_SOMETHING и т.о. весь исполняемый код стоял бы в нормальной функции.

А вот как это сделать в C#?

Пример я повесила к посту. Да, все сделала в 2003-ей студии.
В папке BufReport_DataGrid есть файл BufReportSettingsGrid.cs (блин, у меня на этом компе старая студия, которая не хочет открывать проект... ).
При старте на основной форме есть кнопка "BufRep as grid"

* TestApp.zip (68.65 Кб - загружено 226 раз.)
Записан

холоднокровней, Маня, Ви не на работе
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #13 : 26-04-2007 05:09 » 

Да, все сделала в 2003-ей студии.
Ууууу как всё запущено Ага На рабочем компе такая только стоит Улыбаюсь Дома нема Улыбаюсь
В папке BufReport_DataGrid есть файл BufReportSettingsGrid.cs (блин, у меня на этом компе старая студия, которая не хочет открывать проект... ).
При старте на основной форме есть кнопка "BufRep as grid"
Ок, код скачал. Пойду разбираться если получиться Улыбаюсь
« Последнее редактирование: 26-04-2007 05:10 от MOPO3 » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #14 : 26-04-2007 06:33 » 

Значит так :
Всё что мне пока пришло в голову - это создать свой датагрид класс и наследовать от стандартного.
Что это нам даёт ? А даёт это нам доступ к оверрайду двух методов, которые помогают нам отловить момент начала редактирования в ячейке(два перегруженых метода ColumnStartedEditing. когда это событие отрабатывает, то мы видим иконку карандаша в левой части конкретной строки грида). Далее там уже полёт фантазии. Думаю должно получиться. Если нет, то будем разбираться дальше.

Вот что я предлагаю тебе сделать в файле BufReportSettingsGrid.cs :
создаём ещё один класс. можно в этом же файле, а можеш вынести в другой файл.
Код:
class CustomDataGrid : System.Windows.Forms.DataGrid
{
protected override void ColumnStartedEditing(Rectangle bounds)
{
//base.ColumnStartedEditing (bounds);
                  //делаем что нам нужно
}

protected override void ColumnStartedEditing(Control editingControl)
{
//base.ColumnStartedEditing (editingControl);
                  //делаем что нам нужно
}
}
далее в твоём файле BufReportSettingsGrid.cs строку 138
Код:
this.m_dataGrid = new System.Windows.Forms.DataGrid();

заменяем на
Код:
this.m_dataGrid = new CustomDataGrid();
Пока всё Улыбаюсь Попробуй, посмотрим что получиться.

ЗЫ. В 2003 студии давненько не програмил уже Жаль Так что разбираться будем вместе по ходу дела Улыбаюсь

ЗЫЫ. Вообще, из личного опыта, сколько мне доводилось програмить в НЕТе, так не так всё сказачно на самом деле. Сделать что то качтомизированое под себя - это почти всегда создание своего класса, наследование от стандартного и перегрузка мнооогих методов стандартного класса. Я недавно писал свё собственное контекст меню, нужно было полностью изменять цвета всех элементов и делать градиентные заливки. Так пришлось оверрайдить кучу методов стандартного класса и в итоге код вышел почти на 1000 строк! Так что вот такие вот дела в НЕТе творятся Улыбаюсь
« Последнее редактирование: 26-04-2007 06:38 от MOPO3 » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #15 : 26-04-2007 13:37 » 

Во-первых, огромное спасибо за идею!
Второе - насчет перегрузок я уже поняла... Называется - "мы строили, строили и, наконец, построили"...
Сплошное удовольствие для шкодливых и ооочень старательных ручек... Интересно, это кого-то радует?

Теперь результаты:
1) идею опробовала - работает, т.е. я могу из этого перегруженного метода вызывать все, что мне надо. Уже хорошо и жизнь-то налаживается Ага
2) Проблема - этот метод срабатывает, когда текущая ячейка получает фокус. А мне еще надо какое-то сообщение, которое бы выполнялось при потере ячейкой фокуса.

Далле - еще интереснее Ага Я нашла один ну очень замечательный примерчик на тему "как в колонке вводить только числа" и радостно подумала: "Вот оно, счастье" Ага (примерчик я подвесила)
В результате я уже полдня морочу себе голову, дабы переложить их очень скромный и неприхотливый код на свой лад... Ничего не работает... Я уже вообще ничего не понимаю... Т.е. я где-то очень туплю, но вот где???
Для теста - на основной форме нажать кнопку "DataGrid", на появившейся форме (класс DataGridTest) - выбрать "my example-edit". (обновленный проект - тоже подвесила)




* grid_all.zip (72.41 Кб - загружено 207 раз.)
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #16 : 26-04-2007 14:13 » 

Так, сразу же приятное сообщение Ага:
я нашла свою ошибку, из-за которой не работал пример - в InitDataGridAsTestEdit() надо было еще внести

              m_dataGrid.DataSource = null;

Теперь думаю дальше - надо посмотреть класс DataGridTextBoxColumn, может там есть какое-то событие, которое срабатывает при потере ячейкой фокуса.
Записан

холоднокровней, Маня, Ви не на работе
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines