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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> менеджер форм 
:(
    Опции темы
darkness
Дата 9.6.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Надобно создать некоторый менеджер форм в MDI-приложении отслеживающий какие формы открыты, те сделать Activate, а какие закрыты те конечно Show
Дело в том, что мне нужно отследить не просто открыта ли это форма или нет (проверка Form.Name), но и ещё с каким параметром. Почему так заумно? Дело в том, что некий DataGridView хранит  таблицу, при двойном щелчке на любой Cell открывается  форма отображающая подробную информацию об объекте который описан в "щёлкнутой" записе в Гриде... Т.е. в форму с подробной инфой  передаются некоторые параметры, на основании чего она и формируется... Если с таким параметорм такая форма уже существует, то её просто надо активировать, если же нет, то завново родить.

Задача в принципе несложная. Решил я её через коллекцию (List) структуры, хранящую в себе параметр и само имя, а так же ссылку формы... Код получился немного громоздкий, но всё же рабочий. smile 
Потом возник вопрос: А можно ли отследить запущенные формы по нажатым контроллам, которые из вызвали. Особенно интересует подобный механизм в DataGridView ?

Как вы себе это представляете ?

--------------------
Вина каких стран Вы предпочитаете в это время суток?     (Булгаков. "Мастер и Маргарита") 
PM MAIL   Вверх
Exception
Дата 10.6.2007, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Я бы взял за основу это и модифицировал под свои нужды. В частности, формы следовало бы хранить не в словаре с ключом-строкой, а в словаре с ключом-объектом.
Пусть у нас есть классы Animal, Fish и Bird и отображающие информацию о них дочерние MDI-формы AnimalViewerForm, FishViewerForm и BirdViewerForm.
Для того, чтобы формы можно было создавать, не зная конкретного типа, мы создадим интерфейс IViewer<T>, и пускай каждая из этих форм его реализует:
Код
public interface IViewer<T>
{
    T HoldObject { get; set; }
}

Таким образом, форма AnimalViewerForm должна реализовывать IViewer<Animal> и хранить экземпляр класса Animal:
Код
public class AnimalViewerForm : Form, IViewer<Animal>
{
    private Animal holdAnimal;
    public Animal HoldObject // свойство интерфейса!
    {
        get { return this.holdAnimal; }
        set
        {
            if (value == null) throw new ArgumentNullException ("value");
            this.holdAnimal = value;
            RefreshUI (); // объект изменился - обновляем интерфейс
        }
    }
    private void RefreshUI ()
    {
        this.nameTextBox.Text = this.holdAnimal.Name;
    }
}

По сути, теперь после создания любой формы нужно установить её свойство HoldObject (и пользовательский интерфейс обновится).
Теперь мы реализуем хранилище дочерних форм:
Код
public class MdiForm : Form
{
    private Dictionary<object, Form> childForms = new Dictionary<object, Form> ();
    private TForm GetForm<TForm, TKey> (TKey key)
        where TForm : Form, IViewer<TKey>, new()
    {
        TForm form = this.childForms[key] as TForm;
        if (form == null)
        {
            form = new TForm ();
            form.HoldObject = key;
            form.MdiParent = this;
            this.childForms[key] = form;
        }
        return form;
    }
    private void RemoveForm (object key)
    {
        Form form = this.childForms[key];
        if (form != null)
        {
            form.Dispose ();
            this.childForms.Remove (key);
        }
    }
}

Функция GetForm возратит либо уже созданную форму, либо новую, ассоциированную с объектом key (для каждого объекта будет существовать только одна форма). Функцию RemoveForm я не стал делать обобщённой, потому что реальная проверка соответствия типов нужна только при добавлении в коллекцию.
Теперь можно написать:
Код
this.GetForm<AnimalViewerForm, Animal> (new Animal ("Elephant")).Show (); // создаст новую дочернюю форму и отобразит её
this.GetForm<Animal, AnimalForm> (new Animal ("Elephant")).Hide (); // спрячет уже существующую форму

PM   Вверх
Exception
Дата 10.6.2007, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Кстати, пример со слоном сработает только если мы переопределим метод Equals() в классе Animal.
PM   Вверх
darkness
Дата 12.6.2007, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Exception, а теперь выношу на критику мой код - "небрежный плод моих забав"  smile 

Код


private Form1 MainForm;  //содержит ссылку на родителя MDI

private struct openforms    //структура которая хранит неюбходимые данные
       {
           public string form;    // Имя формы
           public string parametr;  // Параметр, с которым она была вызвана
           public int? hash;         // его высочество хэш данной формы
           public Form ref_form;  // ну и сам адрес в памяти 
           openforms(string form, string parametr)
           {
               this.form = form;
               this.parametr = parametr;
               this.ref_form = null;
               this.hash = null;         
           }
       }

List<openforms> forms = new List<openforms>();   

На мой взгляд, лишнего ничего структура не содержит, это будет видно ниже...
Далее пишем несколько вспомогательных методов(предикаты, и метод создания формы):
Код

private bool real(openforms struc2)
       {
           return this.first.form==struc2.form&&this.first.parametr==struc2.parametr;
       }


        private bool real1(openforms struc3)
        {
            return this.first.hash == struc3.hash; 
        }


        private Form FShow(Form ch)
        {
            ch.MdiParent =  ;
            ch.Show();
            this.StopForm(ch);
            return ch;
        }

Ну и наконец именно то, что и будет рулить нашими всеми формами:
Код

    public  void FSParam(Form f, string str)
        {
            this.first.form=f.Name;
            this.first.parametr=str;
          
            if (forms.Find(new Predicate<openforms>(real)).form == null)  
            {
               //если такой формы с таким параметром нет, то создаём и заносим в коллекцию
                this.first.ref_form = this.FShow(f);
                this.first.hash = this.first.ref_form.GetHashCode();
                forms.Add(this.first);
            }
            else
            {
             //а ежели всё-таки таковая имеется, то просто её активируем
               forms.Find(new Predicate<openforms>(real)).ref_form.Activate();
            }     
        }

Вот.
Ну ещё один из важных моментов, это проследить закрытие формы,  а следовательно избавиться от лишней записи
в forms
Код

public void f_FormClosing(object sender, FormClosingEventArgs e)
        {
            forms.Remove(forms.Find(new Predicate<openforms>(real1)));
        }


Вот в принципе и всё....
Что скажете?





Это сообщение отредактировал(а) darkness - 12.6.2007, 01:51
--------------------
Вина каких стран Вы предпочитаете в это время суток?     (Булгаков. "Мастер и Маргарита") 
PM MAIL   Вверх
Exception
Дата 12.6.2007, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



ИМХО, моё решение получше будет.
Во-первых, я плохо понимаю, зачем хранить хэш формы -- у тебя же, по сути, каждая форма и так уникально идентифицируется переданным ей параметром?
Во-вторых, для изменения типа параметра придётся поменять код (а у меня этого не требуется).
В-третьих, а почему ты используешь строковой параметр? Не лучше ли передавать данные в каком-нибудь специально предназначенном для каждой формы классе?
В-четвёртых, твоё решение, по очевидным причинам, медленнее (поиск с предикатами работает медленнее, чем выборка по ключу).
PM   Вверх
darkness
Дата 13.6.2007, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Exception, 
Цитата

зачем хранить хэш формы

согласен. на выспавшуюся голову гораздо чётче видно обстановку  smile 
Цитата

для изменения типа параметра придётся поменять код

для изменения типа параметра  какого? который string? для моих нужд он всегда будет string...
Цитата

Не лучше ли передавать данные в каком-нибудь специально предназначенном для каждой формы классе?

У меня это строка отправляется потом с запросом в базу....
Цитата

поиск с предикатами работает медленнее, чем выборка по ключу

Вразумил, посему заюзую Dictionary, когда буду править! smile  Спасибо! 

--------------------
Вина каких стран Вы предпочитаете в это время суток?     (Булгаков. "Мастер и Маргарита") 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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