Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Получить ссылку на форму,содержащую мой Компонент


Автор: lam0x7C4 12.7.2007, 17:54
Создал я типа свой компонент ( myComponent: Component), в дизайнере форми бросаю его на форму. Как получить ссилку на эту  форму.

Код

public class myComponent : Component
{
        private Form frmParent;

        // Конструктори.

        public myComponent()
        {
            InitializeComponent();                
        }

        public myComponent(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
            // Желательно где-то здесь найти вот ету форму
            // How ?? --> // frmParent = (Form)container //или чё-то типа того.  
        }
        // .. конструктори
}

Ничего не получаеться  smile (

Автор: Naum 12.7.2007, 18:36
Цитата(lam0x7C4 @  12.7.2007,  18:54 Найти цитируемый пост)
frmParent = (Form)container

А чем это не нравится?

Автор: lam0x7C4 12.7.2007, 18:39
Цитата(Naum @ 12.7.2007,  18:36)
Цитата(lam0x7C4 @  12.7.2007,  18:54 Найти цитируемый пост)
frmParent = (Form)container

А чем это не нравится?

Не работает.
После етого frmParent == null.

Автор: tol05 12.7.2007, 19:19
Цитата(lam0x7C4 @  12.7.2007,  18:39 Найти цитируемый пост)
После етого frmParent == null

значит, контрол принадлежит не форме, а контолу на этой форме (панели, например, или GroupBox-у)

Если контейнер принял твой контрол в свою коллекцию (container.Add(this); сработало), то он не может быть равен null.
контейнер не приводится к типу Form (базовому для всех форм) - Значит контейнер - просто не форма

Автор: lam0x7C4 13.7.2007, 09:40
Просто у меня не контрол( Control ), a компонент( Component ). Ето немножко разние вещи. В дизайнере он[Component] бросаеться не на форму, он бросаеться на полоску, что под формой( туда куда MenuStrip бросаетья )...

Ну предположим, принадлежит компонент не форме, а контролу. Как тогда контрол найти?

Проблема вроде елементарная, но  smile .

Автор: tol05 13.7.2007, 10:09
я говорил об общем принципе, когда упоминал о контроле. Это не принципиально. 
Как найти? Ну допустим, есть форма, на ней панель, на панели - кнопка. Тогда так:
Код

public Form1()
{
    InitializeComponent();
        
    Panel p = new Panel();
    p.Name = "myPanel";
    this.Controls.Add(p);

    Button b = new Button();
    b.Name = "myButton";
    p.Controls.Add(b);

    Panel unknownPanel;
    Button unknownButton; 

    foreach( Control control in this.Controls )
    {
        unknownPanel = control as Panel;
        if(!Equals(unknownPanel, null) && unknownPanel.Name == "myPanel") break;
    }
    foreach(Control control in unknownPanel.Controls)
    {
        unknownButton = control as Button;
        if(!Equals(unknownButton, null) && unknownButton.Name == "myButton") break;
    }
}

можно и так...
Код

Panel unknownPanel = this.Controls.Find("myPanel", true)[0] as Panel;
Button unknownButton = this.Controls.Find("myButton", true)[0] as Button;

тогда все ищется только через форму. Но "[0]" - сам понимаешь, криво... Все равно потом цикл по всем найденным делать нужно.

Автор: Naum 13.7.2007, 10:20
Цитата(lam0x7C4 @  13.7.2007,  10:40 Найти цитируемый пост)
Как тогда контрол найти?

Код

frmParent = (Control)container;

Автор: lam0x7C4 13.7.2007, 10:46
Цитата(Naum @ 13.7.2007,  10:20)
Цитата(lam0x7C4 @  13.7.2007,  10:40 Найти цитируемый пост)
Как тогда контрол найти?

Код

frmParent = (Control)container;

Unable to cast object of type 'System.ComponentModel.Container' to type 'System.Windows.Forms.Control'.



tol05, пасиба за инфу. Но проблема немножко не в этом.

Мне не надо находить контрол, зная форму.
Все, что у меня есть, ето компонент, который я буду потом юзать на разных формах . Тоесть, форму надо всегда определять в конструкторе.(Хотя я уже сомневаюсь, что ето реально)

Код

public class myComponent : Component
{
        private Form frmParent;

        // Конструктори.

        public myComponent()
        {
            InitializeComponent();                
        }

        public myComponent(IContainer container)
        {
            container.Add(this);// <-- по идее, отсюда можна найти форму.
            InitializeComponent();            
        }
        // .. конструктори
}


p.s.Опять же, если бы это был Control, я бы форму уже давно нашел(там просто), у меня Component.


p.p.s. Все равно, всем пасиба за помощь smile

Автор: Naum 13.7.2007, 13:52
Цитата(lam0x7C4 @  13.7.2007,  11:46 Найти цитируемый пост)
Цитата(Naum @ 13.7.2007,  10:20)
Цитата(lam0x7C4 @  13.7.2007,  10:40 Найти цитируемый пост)
Как тогда контрол найти?

Выделить всёкод C#
1:
    
frmParent = (Control)container;

Unable to cast object of type 'System.ComponentModel.Container' to type 'System.Windows.Forms.Control'.

Ссори. frmParent = (ContainerControl)container;
Types derived by ContainerControl:
  • System.Windows.Forms.Form
  • System.Windows.Forms.PropertyGrid
  • System.Windows.Forms.SplitContainer
  • System.Windows.Forms.ToolStripContainer
  • System.Windows.Forms.ToolStripPanel
  • System.Windows.Forms.UpDownBase
  • System.Windows.Forms.UserControl


Автор: lam0x7C4 13.7.2007, 15:04
Цитата
10:40 Найти цитируемый пост)

Цитата
Выделить всёкод C#

 smile 

Пасиба  smile .
Ща потестирую...


Автор: Naum 13.7.2007, 16:04
А еще в отладчике можно посмотреть какого типа IConteiner передается в конструктор твоего компонента.

Автор: lam0x7C4 13.7.2007, 17:38
ммм, 
чё-то не очень оно хочет работать  smile .Я уже весь день над етим просидел и ничего уже не думаеться smile  .
Короче: smile .


Автор: mr.DUDA 13.7.2007, 22:57
Извиняюсь, а this.Parent что не катит ?

Автор: lam0x7C4 16.7.2007, 17:05
Цитата(mr.DUDA @ 13.7.2007,  22:57)
Извиняюсь, а this.Parent что не катит ?

Сорри, что не отвечал так долго - инет глючит.
Неа, в даном случае не катит. Просто надо получить ссилку на форму еще до того как она становиться видимой для юзера. И вот фишка в том, что до етого момента this.Parent == null. Нужно ловить ссилку на форму в каком-то собитии(Пробовал "Load" компонента, но и там не катит, больше не нашел подходящих событий). 

--
Ах, да. Свойства Parent в компонента нет.

Автор: mr.DUDA 16.7.2007, 22:59
Метод FindForm ещё есть.

Автор: lam0x7C4 17.7.2007, 12:16
Цитата(mr.DUDA @ 16.7.2007,  22:59)
Метод FindForm ещё есть.

Спасиба, пригодиться smile

Думаю, тему можно закривать.

Автор: Mr_Smith 1.4.2008, 10:05
Рановато закрывать, потому как итог такой - много флуда, а решение так и не найдено.

Автор: mr.DUDA 1.4.2008, 10:40
Mr_Smith, на основании чего сделан столь глубокомысленный вывод?

Автор: Mr_Smith 1.4.2008, 10:54
Потому как все упорно рассказывали как получить свойство от контрола, а не от компонента, а это разные вещи.

Сделать можно так:
http://www.codeproject.com/KB/smart/VBNET__Windows_Forms_.aspx

а так сделали микрософтовцы в своем еррор провайдере:
Код

public override ISite Site
{
    set
    {
        base.Site = value;
        if (value != null)
        {
            IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (service != null)
            {
                IComponent rootComponent = service.RootComponent;
                if (rootComponent is ContainerControl)
                {
                    this.ContainerControl = (ContainerControl) rootComponent;
                }
            }
        }
    }
}


Код

[DefaultValue((string) null), SRCategory("CatData"), SRDescription("ErrorProviderContainerControlDescr")]
public ContainerControl : ContainerControl
{
    [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows), UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows)]
    get
    {
        return this.parentControl;
    }
    set
    {
        if (this.parentControl != value)
        {
            if (this.parentControl != null)
            {
                this.parentControl.BindingContextChanged -= this.propChangedEvent;
            }
            this.parentControl = value;
            if (this.parentControl != null)
            {
                this.parentControl.BindingContextChanged += this.propChangedEvent;
            }
            this.Set_ErrorManager(this.DataSource, this.DataMember, true);
        }
    }
}


Автор: mr.DUDA 1.4.2008, 10:59
Мда, компонент и контрол действительно разные вещи, в Controls некоторые не найдёшь.

Автор: Mr_Smith 1.4.2008, 11:29
Хмммм.... попробовал и как в статье и как в примере.  не получается. поделитесь кодом если у кого получится, вполне вероятно что все дело в кривизне моих рук

Автор: Mr_Smith 2.4.2008, 04:59
Покамлав, получил такое решение:

Код

[Designer(typeof(FormPersisterDesigner), typeof(System.ComponentModel.Design.IDesigner))]
    public partial class FormSettingsSaverComponent : Component
    {
        public Form Parent;
        public FormSettingsSaverComponent() 
        {
        }

        public FormSettingsSaverComponent(IContainer container) 
        {
            container.Add(this);
        }
      ...
    }

    public class FormPersisterDesigner : ComponentDesigner
    {
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            FormSettingsSaverComponent formSettingsSaverComponent = this.Component as FormSettingsSaverComponent;
            IDesignerHost idh = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
            Form parentForm = idh.RootComponent as Form;
            if(parentForm == null)
            {
                throw new ApplicationException("A Form host must be a top-level form.");
            }
            formSettingsSaverComponent.Parent = parentForm;
        }
    }




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