C # - Выклік функцыі ў бацькоўскай форме

Я спрабую выклікаць функцыю ў асноўнай форме з іншай формы ... Дасталі ўжо назваць простую функцыю, абвясціўшы яго публічным статычным ў асноўнай форме, але я не магу назваць неабходнай адзін. Функцыя для выкліку:

    public static void spotcall()
    {
        string dial = Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("INTERCOMCS").GetValue("DIAL").ToString();
        MainForm.txtSendKeys.Text = dial;// Here it asks me for a reference to an object.


        foreach (char c in txtSendKeys.Text)
        {
            sideapp.Keyboard.SendKey(c.ToString(), checkBoxPrivate.Checked);
        }
        txtSendKeys.Clear();
    }

Працэдура Я выкарыстоўваю, каб выклікаць яго з формы дзіцяці:

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Text = "Hoho";
        MainForm.spotcall();
    }

Я цалкам прызнаю, што мне не хапае нейкай тэорыі пра C#, але, як гэта часта бывае, я проста павінен зрабіць гэта для маёй працы, таму я чакаю, каб атрымаць дапамогу, калі я выпадкова не атрымаць да вырашэння па сабе. Дзякуй :)

1
Вы можаце даць нам паведамленне пра памылку вы атрымліваеце? Гэта не збор, ці не так? Што кажа кампілятар?
дададзена аўтар Ed Plunkett, крыніца
Ён просіць у мяне і аб'екты спасылкі на «txtSendKeys». Паведамленне на французскай, таму не можа атрымаць дакладны тэкст, хоць.
дададзена аўтар Grigory Kornilov, крыніца

7 адказы

Вы не можаце спасылацца на прыклады кіравання на вашым MainForm у статычным метадзе. Як кампілятар кажа вам, што вам трэба асобнік формы для таго, каб абнавіць рэчы, як TextBoxes. Без асобніка, дзе б значэння, якія вы спрабуеце абнавіць ісці?

Я не ведаю дакладна, як ствараецца даччыная форма, але адзін з спосабаў вы можаце выклікаць метады на вашым MainForm будзе прадастаўляць спасылку на ваш MainForm <�код /> напрыклад, непасрэдна дзіця форма. Гэта можа быць праз канструктар ці якой-небудзь грамадскай уласнасці.

<�Моцны> Напрыклад,

public class ChildForm : Form {

    public MainForm MyParent { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Text = "Hoho";

       //Now your child can access the instance of MainForm directly
        this.MyParent.spotcall(); 
    }   

}

Мяркуючы, што вы ствараеце ChildForm ўнутры MainForm код, каб даць дзіцяці спасылку даволі просты:

var childForm = new ChildForm();
childForm.MyParent = this;//this is a `MainForm` in this case
childForm.Show();

Акрамя таго, неабходна будзе зрабіць spotcall метад асобніка, а не статычны метад, і выдаліць статычную спасылку на MainForm у кодзе:

public void spotcall()
{
    string dial = Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("INTERCOMCS").GetValue("DIAL").ToString();
   //Now it no longer asks you for a reference, you have one!
    txtSendKeys.Text = dial;

    foreach (char c in txtSendKeys.Text)
    {
        sideapp.Keyboard.SendKey(c.ToString(), checkBoxPrivate.Checked);
    }
    txtSendKeys.Clear();
}
5
дададзена

Я думаю, што правільны спосаб зрабіць гэта складаецца ў выкарыстанні дэлегатаў. Такім чынам, ваша форма (акно) не павінна нічога ведаць аб бацькоўскай форме (форма можа быць адкрыта з розных бацькоўскіх форм).

Дапусцім, мы хочам, каб выклікаць функцыю ў бацькоўскай форме, калі даччыная форма зачыняецца (не паказваючы форму як мадальны).

У верхняй частцы формы дзіцяці стварыць дэлегат:

    public delegate void CloseEvent();
    public CloseEvent WindowClosed;

Стварыць падзея формы закрыцця і яго называюць свой дэлегат:

    private void child_FormClosing(object sender, FormClosingEventArgs e)
    {
      WindowClosed();
    }

Кнопка ў бацькоўскай форме можа паказаць форму дзіцяці і ўсталяваць функцыю зваротнага выкліку:

    private ChildForm childform = null;

    private void buttonShowChildForm_Click(object sender, EventArgs e)
    {
      if (childform == null)
      {
        childform = new ChildForm();
        childform.WindowClosed += childClosed;
        childform.Show();
      } else
      {
        childform.BringToFront();
      }
    }

    private void childClosed()
    {
        childform = null;
    }

У гэтым прыкладзе мы выкарыстоўваем кнопку, каб адкрыць новую форму, якая не блакуе бацькоўскі выгляд. Калі карыстальнік спрабуе адкрыць форму ў другі раз, мы проста давесці існуючую форму на фронт, каб паказаць яго карыстальніку. Калі форма зачынена мы ўсталёўваем аб'ект у нуль, так што ў наступны раз, калі мы націсніце на кнопку новая форма адкрыта, таму што стары быў размешчаны ў закрытым стане.

З найлепшымі пажаданнямі   Hans Фрэзерныя ...

1
дададзена

Калі вы ствараеце статычную функцыю, вы не можаце спасылацца на глабальныя зменныя ўнутры функцыі, якія не з'яўляюцца статычнымі, а таксама.

Таму, каб для spotcall быць статычнымі, вы павінны выдаліць спасылку на txtSendKeys (я мяркую, што гэта тэкставае поле, якое вы стварылі ў іншым месцы ў форме) або txtSendKeys павінен быць абвешчаны ў статычнай функцыі.

дадаткова:

Вы атрымалі значэнне для txtSendKeys.Text ў папярэднім радку, з дапамогай пераменнага набору. Замест спасылкі txtSendKeys.Text наогул, я думаю, вы маглі б проста выкарыстоўваць пераменны дыск для завяршэння функцыі і выхадам з функцыі статычных (вам ясна, гэта ў рэшце рэшт так ці інакш).

public static void spotcall()
    {
        string dial = Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("INTERCOMCS").GetValue("DIAL").ToString();


        foreach (char c in dial)
        {
            sideapp.Keyboard.SendKey(c.ToString(), checkBoxPrivate.Checked);
        }            
    }

Нягледзячы на ​​тое, што яшчэ захавалася тое ж пытанне, вы, верагодна, сутыкнецеся з checkBoxPrivate.Checked.

Вы можаце змяніць яго, каб зрабіць лагічны аргумент.

public static void spotcall(Boolean PrivateChecked)
    {
        string dial = Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("INTERCOMCS").GetValue("DIAL").ToString();               

        foreach (char c in dial)
        {
            sideapp.Keyboard.SendKey(c.ToString(), PrivateChecked);
        }

    }
1
дададзена
Я думаю, што ён мае патрэбу ў адваротным: spotcall() павінна быць метадам асобніка. txtSendKeys, верагодна, ўласцівасць прывязаны да элемента кіравання, створанага ў выглядзе канструктара. Ён не мог бы выдаць яго ў іншым месцы, і ён не можа нічога карыснага зрабіць без яго. Ён проста павінен атрымаць Ахольд асобніка MainForm ў тым месцы, дзе ён называе spotcall ().
дададзена аўтар Ed Plunkett, крыніца
О, я разумею, што вы маеце на ўвазе. Я не надаваў дастатковай увагі на тое, што яго код быў на самай справе робіць. Вы вельмі правільна, txtSendKeys не належыць там наогул. Ён выкарыстоўвае элемент карыстацкага інтэрфейсу ў якасці рэзервовай зменнай тэмп. Усё, што ён сапраўды робіць, пасылаючы значэнне ключа рэестра дзе-небудзь яшчэ. Дзякуй за нязгоду шмат больш паважліва, чым я на самай справе заслужылі! :)
дададзена аўтар Ed Plunkett, крыніца
Вы павінны пакласці, што ў сваім адказе - усё кажа аб статычных супраць, напрыклад, але зусім бязвыплатнае выкарыстанні txtSendKeys на самай справе больш фундаментальная памылка. Я не збіраюся пакласці, што ў маім адказе, таму што вы злавілі яго.
дададзена аўтар Ed Plunkett, крыніца
Эй, я, нарэшце, думаю, што складаныя рэчы занадта шмат ... Гэта не было нават форма дзіцяці, а проста іншы. Я нарэшце-то рэч, паставіўшы ўсю функцыю ў маёй «форме дзіцяці», змяняючы яго для таго, каб выбіць усё, што ставіцца да «MainForm». Дзякуй за вашу дапамогу, гэта сапраўды прыемна.
дададзена аўтар Grigory Kornilov, крыніца
Я не згодны, з павагай. Ён атрымаў значэнне для txtSendKeys.Text ў папярэднім радку, з дапамогай пераменнага набору. Замест спасылкі txtSendKeys.Text наогул, я думаю, ён мог бы проста выкарыстоўваць пераменны дыск для завяршэння функцыі і выхаду з функцыі статычных (ён ачышчае яго ў канцы ў любым выпадку). Нягледзячы на ​​тое, што яшчэ захавалася тое ж пытанне, ён, верагодна, сутыкнуцца з checkBoxPrivate.Checked ... але, спадзяюся, рашэнне гэтага пытання прывядзе яго да рашэння, што добра.
дададзена аўтар Chris, крыніца
Я разумею, што. Я дадаў яго.
дададзена аўтар Chris, крыніца
Вядома няма праблем.
дададзена аўтар Chris, крыніца

Вы не можаце атрымаць доступ да нестатическим членам у статычным кантэксце, што азначае, што вы павінны з txtSendKeys статычным, або зрабіць вашу функцыю нестатической.

1
дададзена

Вы можаце змясціць агульны код у трэці клас, даступны для абедзвюх формаў. Так, напрыклад:

public class static HelperFunctions
{

    public static void spotcall()
    {
        . . . 
    }
}

затым заменіце

MainForm.spotcall()

з

HelperFunctions.spotcall()
0
дададзена

<�Код> MainForm гэта проста клас. Ён мае структуру класа. Але толькі дадзеныя, якія вы можаце атрымаць з яго статычным дадзеныя.

But an instance of that class appears when you do: MainForm MyFormInstance = new MainForm();

<�Код> MainForm можа быць выкарыстаны толькі для доступу статычных членаў (метады, ўласцівасці ...). Калі вы хочаце, каб атрымаць txtSendKeys , вы павінны атрымаць яго з асобніка (спасылка на аб'ект). Гэта таму, што тэкставае поле не з'яўляецца статычным, так што існуе толькі ў выпадках формы.

Такім чынам, вы павінны зрабіць наступнае:

  • Make spotcall NOT static.
  • Put in child form a variable MainForm MyParentMainForm;
  • When you call the child, set that MyParentMainForm with the instance of the mainform. If it's being called from the main form, you can get the instance with the this keyword.
  • Inside child form, call MyParentMainForm.spotcall

PS: Я не ўпэўнены, калі ёсць нешта накшталт рэальнай формы дзіцяці або калі вы проста выклікаеце новыя формы ад іншага. Калі ёсць на самой справе дзіця формы, вы можаце атрымаць Parent ўласцівасць для доступу да экземпляра галоўнай формы.

0
дададзена

Гэта свайго роду «дызайн малюнка» пытанне, які я буду распрацаваць, але я магу паспрабаваць растлумачыць самы прамы спосаб вырашыць гэтую праблему, калі вы не чакаеце, што гэтая праграма моцна зменіцца. «Статычныя» рэчы існуюць толькі <�моцны> адзін раз - адзін раз ва ўсёй заяўцы. Калі пераменная або функцыя з'яўляецца статычным, гэта значна прасцей атрымаць доступ з любога месца ў праграме; але вы не можаце атрымаць доступ звязаныя з ім дадзеныя аб'екта, таму што вы не паказвае на пэўны асобнік гэтага аб'екта (гэта значыць, у вас ёсць сем MainForms. Які з іх вы называеце гэтую функцыю?) Так як стандартны дызайн WinForm чакае, што вы маглі б мець сем копій MainForm адлюстроўваюць ўсе зменныя, звязаныя будуць асобнік пераменныя або нестатическая. Тым не менш, калі вы не чакаеце ніколі мець другі MainForm, то вы можаце ўзяць «адзіночкі» падыход, і ёсць просты спосаб доступу да вашай аднаго асобніка.

partial class MainForm {

   //only including the code that I'm adding; I'm sure there's a lot of stuff in your form.
    public static MainForm Instance { public get; private set; }

    protected void onInitialize() {//You need to hook this part up yourself.
        Instance = this;
    }
}

partial class SubForm {
    protected void onImportantButton() {
        MainForm.Instance.doImportantThing()
    }
}

Увод занадта актыўная логікі дадзеных змяняюцца ў класе формы з'яўляецца даволі распаўсюджанай праблемай з кодам многіх пачаткоўцаў. Гэта не жудасная рэч - вы не хочаце, каб зрабіць 5 кантрольных класаў толькі для простай рэчы, якую вы спрабуеце. Як код становіцца больш складаным, вы пачынаеце знайсці некаторыя рэчы будуць мець больш сэнсу рухацца да «падузровень» класаў, якія не ўзаемадзейнічаюць з карыстальнікам (так, некаторыя дзень, калі гэты час перакадзіруецца як праграма сервера , вы маглі б выкінуць класы формаў, а проста выкарыстоўваць лагічныя класы - тэарэтычна). Ён таксама займае некаторы час для многіх праграмістаў, каб зразумець усю канцэпцыю аб'екта «асобнікі», і «кантэкст», што функцыя выклікаецца.

0
дададзена
Гэта жудасная практыка і прывядзе да якая распаўсюджваецца дрэнны дызайн і робіць яго значна цяжэй для людзей, каб даведацца, як <�я> правільна </я> адрас гэтай праблемы.
дададзена аўтар Servy, крыніца
Калі пачатковец вучацца на працы, у той жа час, як чакаюцца, хутка пісаць код з фактычным выкарыстаннем, гэта амаль напэўна, што адзін не збіраюцца пісаць правільнае праектаванне першых некалькі разоў; у нейкім сэнсе, я думаю, што больш важна, каб людзі робяць простыя памылкі дызайну-шаблоны на ранняй стадыі, каб яны маглі лепш зразумець заканамернасці, калі яны пішуць пазнейшыя праграмы. Але прасіць кагосьці, каб цалкам перапісаць праграму, якую яны хутка напісалі для сваёй працы з'яўляецца рэальнай ўніз клюшкай. Тым не менш, маё перакананне ў тым, што гэта невялікая праграма, якая ніколі не будзе маштабавацца ўверх.
дададзена аўтар Katana314, крыніца
Вялікі дзякуй за вашыя парады. Тым не менш, нават калі мая частка коды што-то на самай справе асноўнае, я на самой справе intented дадаць функцыю да велізарных рэчам, то ёсць actuallly SDK з прыкладання на баку, што я не магу паставіць уверх-уніз;) Дарэчы, гэта вельмі дрэнна concieved, а таксама.
дададзена аўтар Grigory Kornilov, крыніца