| | |
| Stránka: 1 z 1
| [ Príspevkov: 16 ] | |
Autor | Správa |
---|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 |
Zdravím, potrebovala by som pomôcť so situáciou kde z Form1 kde je umiestnený panel som načítala UserControl1, tento UserControl1 obsahuje Button ktorý mi zobrazí v tom istom panely UserControl2... môj kód vyzerá takto: Form1: Kód: public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void form2_SomethingHappened(object sender, EventArgs e) { UserControl1 control1 = (UserControl1)sender;
control1.Dock = DockStyle.Fill; panel1.Controls.Add(control1);
UserControl2 control2 = new UserControl2(); control2.Dock = DockStyle.Fill; panel1.Controls.Clear(); panel1.Controls.Add(control2); }
private void Form1_Load(object sender, EventArgs e) {
UserControl1 control1 = new UserControl1(); control1.Dock = DockStyle.Fill; control1.SomethingHappened += form2_SomethingHappened; panel1.Controls.Clear(); panel1.Controls.Add(control1); }
UserControl1: Kód: public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } public event EventHandler SomethingHappened; private void button1_Click(object sender, EventArgs e) { if (SomethingHappened != null) // notify listeners, if any SomethingHappened(this, EventArgs.Empty); } }
- všetko funguje ako má avšak chcela by som sa z UserControl2 vrátiť naspäť do UserControl1 cez Button, avšak neviem ako to spraviť aby sa všetko odohrávala v jednom Panely. Budem vďačná za všetky nápady
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
V prvom rade, nesúvisí to síce s problémom, ale ak nemáš naozaj dobrý dôvod, skús sa naučiť radšej WPF a nie winforms... Mnoho vecí sa tam rieši jednoduchšie, prehľadnejšie atď. A čo sa týka tejto tvojej dilemy.... Tých spôsobov, ako to dosiahnuť, je relatívne veľa. Napríklad môžeš využiť podobnú techniku ako teraz, tj. budeš mať definovaný event, pričom ho budeš obsluhovať vo forme1. Rozdiel bude v tom, že nepoužiješ EventArgs, ale vytvoríš si nejaké custom argumenty, napr NavigationArgs... Menší náčrt, ako to myslím: Kód: public enum MyControl { UserControl1, UserControl2 } public class NavigationArgs { public MyControl NavigateToControl { get; private set; } public NavigationArgs(MyControl target) { NavigateToControl = target; } }
náčrt Form1 Kód: public partial class Form1 : Form { public Form1() { InitializeComponent(); }
protected void Form1_Load(object sender, EventArgs e) { UserControl1 control1 = new UserControl1(); ChangeControlTo(control1); }
protected void ChangeControlTo(ICustomControl control) { // todo: tu by bolo fajn zistiť, či je v paneli nejaký custom control a ak áno, odstrániť event handler (control.PerformNavigation -= performNavigation), // prípadne aj zavolať dispose atď... podľa potreby
control.Dock = DockStyle.Fill; control.PerformNavigation += performNavigation; panel1.Controls.Clear(); panel1.Controls.Add(control); }
protected void performNavigation(object sender, NavigationArgs e) { ICustomControl control;
switch (e.NavigateToControl) { default: case MyControl.UserControl1: control = new UserControl1(); break; case MyControl.UserControl2: control = new UserControl2(); break; }
ChangeControlTo(control); } }
jednoduchý interface: Kód: public delegate void PerformNavigationHandler(object sender, NavigationArgs e);
public interface ICustomControl { event PerformNavigationHandler PerformNavigation; }
a implementácia, napr CustomControl1 a 2 Kód: public partial class UserControl1 : UserControl, ICustomControl { public event PerformNavigationHandler PerformNavigation;
protected void button1_Click(object sender, EventArgs e) { if (PerformNavigation != null) PerformNavigation(this, new NavigationArgs(MyControl.UserControl2)); } }
public partial class UserControl2 : UserControl, ICustomControl { public event PerformNavigationHandler PerformNavigation;
protected void button1_Click(object sender, EventArgs e) { if (PerformNavigation != null) PerformNavigation(this, new NavigationArgs(MyControl.UserControl1)); } }
Len upozorňujem, je veľa hodín, netestol som to, môžu tam byť chyby, ale hádam ti to dá cca nápad, ako sa to dá zrealizovať... Samozrejme si treba uvedomiť, že pri tomto prístupe získaš vždy novú inštanciu... Ak chceš naozaj nejakú navigáciu smerom späť, musíš si dané inštancie niekde ukladať (alebo údaje z nich) a potom obnoviť, ak existujú. Ak nie, vytvoriť novú inštanciu a tú použiť.. A tiež ako som uviedol v komentári, nezabudni odstrániť eventhandler a prípadne aj zavolať dispose na predchádzajúcom controle. Samozrejme, nie je to jediné riešenie... Treba si vybrať také, ktoré ti bude najviac vyhovovať..
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 15.03.2015 11:28 | |
|
Óha ďakujem, vyskúšala som Váš kód avšak vo Form1 v ChangeControlTo my stále zobrazuje chybu v kóde Kód: panel1.Controls.Add(control); Chyba je: Argument 1: cannot convert from 'pokusspanelmi.ICustomControl' to 'System.Windows.Forms.Control" Taktúto podobnú chybu som videla keď som pracovala s itextsharp a defaultne my všetky štýly napr. pre písmo chcelo brať so System.Drawing ale v tomto prípade neviem ako to mám zmeniť lebo s týmto prepínaním medzi panelmi som stratená V škole sme pracovali vždy len s WindowsForms a o WPF som ani nepočula ale vyzerá to pokročilejšie určite sa na to dám
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
Jasné, chybička se vloudila Hlášku vypisuje preto, lebo nie je momentálne žiaden vzťah medzi UserControl a ICustomControl. Bolo by asi lepšie miesto interface použiť v tomto prípade abstraktnú triedu, ktorá bude dediť z UserControl a bude obsahovať ten event a prípadne ďalšie veci, ktoré potrebuješ, aby tie prvky mali spoločné.. Čiže dačo takéto: Kód: public abstract MyControlBase : UserControl { public delegate void PerformNavigationHandler(object sender, NavigationArgs e); public event PerformNavigationHandler PerformNavigation; }
Dané custom controly teda nebudú dediť priamo z UserControl, ale z tejto základnej triedy. Tiež sme sa tým zbavili duplicity (netreba napr definovať event v každom potomkovi). Teraz len zmeníš všade ICustomControl na MyControlBase, a hádam by to už malo ísť..
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 15.03.2015 13:14 | |
|
Ok, stále tam je nejaký problém vedeli by ste mi v tom nájsť chybu? kód vyzerá teda takto: Form1: Kód: public abstract class MyControlBase : UserControl { public delegate void PerformNavigationHandler(object sender, NavigationArgs e); public event PerformNavigationHandler PerformNavigation; }
public enum MyControl { UserControl1, UserControl2 }
public class NavigationArgs { public MyControl NavigateToControl { get; private set; }
public NavigationArgs(MyControl target) { NavigateToControl = target; } } public partial class Form1 : Form { public Form1() { InitializeComponent(); }
protected void Form1_Load(object sender, EventArgs e) { UserControl1 control1 = new UserControl1(); ChangeControlTo(control1); }
protected void ChangeControlTo(MyControlBase control) { control.PerformNavigation += performNavigation; panel1.Controls.Clear(); panel1.Controls.Add(control);
}
protected void performNavigation(object sender, NavigationArgs e) { MyControlBase control;
switch (e.NavigateToControl) { default: case MyControl.UserControl1: control = new UserControl1(); break; case MyControl.UserControl2: control = new UserControl2(); break; }
ChangeControlTo(control); } } }
UserControl1: Kód: public partial class UserControl1 : MyControlBase { public event PerformNavigationHandler PerformNavigation;
protected void button1_Click(object sender, EventArgs e) { if (PerformNavigation != null) PerformNavigation(this, new NavigationArgs(MyControl.UserControl2)); } public UserControl1() { InitializeComponent(); } }
Nevypisuje mi to chyby ale varovania a problém je PerformNavigation ... prosím Vás vedeli by ste mi v tom nájsť chybu nezavolala som v UserControls správne PerformNavigation? Chyby: The designer must create an instance of type 'pokusspanelmi.MyControlBase' but it cannot because the type is declared as abstract. 'pokusspanelmi.UserControl1.PerformNavigation' hides inherited member 'pokusspanelmi.MyControlBase.PerformNavigation'
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
Zruš pri tej triede "abstract" a v jednotlivých UserControl čo si vytvorila vymaž ten event, nakoľko ten je definovaný už v triede, z ktorej dedíš. Daj vedieť či pomohlo...
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 15.03.2015 13:44 | |
|
Vymazala som "abstract" aj v UserControl eventy a vykazuje mi to chyby: Pri UserControl kde je použitý PerformNavigation: The event 'panely.MyControlBase.PerformNavigation' can only appear on the left hand side of += or -= (except when used from within the type 'panely.MyControlBase') a varovania: The designer must create an instance of type 'panely.MyControlBase' but it cannot because the type is declared as abstract. čož tomu moc nechápem veď som vymazala abstract takže už je to obyčajná trieda.... už to vyzerá ale byť blízko a fakt neviem sa z tohoto vymotať
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
To je tak, keď píšem spamäti a netestujem to.. Vyvolávať dedený event takto nejde, treba kód trošku upraviť.. Toto som teraz otestoval a funguje... Dalo by sa to krajšie, efektívnejšie atď, ale neviem do akej miery by si to využila a neskutočne by to skomplikovalo vysvetľovanie.. To už hádam zvládneš prípadne aj sama, prípadne to potom treba rozdeliť do viacerých čiastkových problémov Ak niečo nie je jasné, kľudne sa pýtaj... Form1: Kód: public partial class Form1 : Form { public Form1() { InitializeComponent(); }
void Form1_Load(object sender, EventArgs e) { UserControl1 control1 = new UserControl1(); ChangeControlTo(control1); }
void ChangeControlTo(MyControlBase control) { Unsubscribe();
control.PerformNavigation += performNavigation; panel1.Controls.Clear(); panel1.Controls.Add(control); }
void Unsubscribe() { if (panel1.Controls.Count > 0) { foreach (Control c in panel1.Controls) { MyControlBase previous = c as MyControlBase; if (previous != null) { previous.PerformNavigation -= performNavigation; } } } }
void performNavigation(object sender, NavigationArgs e) { MyControlBase control;
switch (e.NavigateToControl) { default: case MyControl.UserControl1: control = new UserControl1(); break; case MyControl.UserControl2: control = new UserControl2(); break; }
ChangeControlTo(control); } }
MyControlBase, enumerácia MyControl a argumenty: Kód: public class MyControlBase : UserControl { public delegate void PerformNavigationHandler(object sender, NavigationArgs e); public event PerformNavigationHandler PerformNavigation;
public virtual void OnNavigating(NavigationArgs args) { if (PerformNavigation != null) PerformNavigation(this, args); } }
public enum MyControl { UserControl1, UserControl2 }
public class NavigationArgs { public MyControl NavigateToControl { get; private set; }
public NavigationArgs(MyControl target) { NavigateToControl = target; } }
a napr UserControl1 Kód: public partial class UserControl1 : MyControlBase { public UserControl1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { OnNavigating(new NavigationArgs(MyControl.UserControl2)); } }
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 15.03.2015 15:06 | |
|
Super, ďakujem naozaj ste mi pomohli a ja som sa stým tak trápila.
|
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 17.03.2015 0:24 | |
|
Ak sa ešte môžem k tejto téme vyjadriť.. je možnosť preniesť údaje z jedného panelu do druhého?
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
Aké údaje? Ono vždy je nejaký spôsob, len riešenie závisí od konkrétnej situácie...
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 17.03.2015 11:21 | |
|
Napr. v UserControl1 mám DataGridView kde som načítala údaje z MySQL databázy, taktiež obsahuje button Edit. Po kliknutí sa mi vlastne otvorí v panely UserControl2 kde sú textboxy kde by mali byť načítané údaje z DataGridView kde by ich používateľ upravil a uložil. Avšak riešila som to pôvodne takto: Mám dva formuláre vyrobca a vyrobca_edit, vo formulári vyrobca (obsahuje DataGridView) po stlačení button Edit som vytvorila konštruktor a tovorí sa nový formulár v novom okne: Kód: vyrobca_edit vyredit= new vyrobca_edit(dgvVyrobca.SelectedRows[0].Cells["id_vyrobca"].Value.ToString()); vyredit.Show(); a potom vo formulári vyrobca_edit som si zavolala hodnotu do textboxu: Kód: public vyrobca_edit(string id) { InitializeComponent(); tbid_vyrobca.Text=id; } - ono to funguje, avšak chcela som aby sa to používateľovi zobrazovalo v jednom panely tak som použila metódu ktorú ste mi vyriešil čiže UserControl1= vyrobca, UserControl2= vyrobca_edit a volám ich vlastne z formulára Form, avšak moju metódu s prenášaním údajov už nemôžem použiť lebo vo Form je vlastne vytvorený ďalší konstruktor Kód: case MyControl.UserControl2: control=new UserControl2(); break; a ono sa to potom všetko bije lebo údaje ktoré chcem preniesť sú z UserControl1(výrobca) do UserControl2(vyrobca_edit). Dá sa to aj nejakým iným spôsobom popresúvať?
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
Jasné, dá sa... Spôsobov je zasa viacero. Môžeš napríklad rozšíriť triedu NavigationArgs, ktorú sme si vytvorili, o ďalšiu vlastnosť... Povedzme takto: Kód: public class NavigationArgs { public MyControl NavigateToControl { get; private set; } public int EntityId { get; private set; }
public NavigationArgs(MyControl target) { NavigateToControl = target; } public NavigationArgs(MyControl target, int entityId) { NavigateToControl = target; EntityId = entityId; } }
Potom v UserControl1: Kód: private void button1_Click(object sender, EventArgs e) { OnNavigating(new NavigationArgs(MyControl.UserControl2, entityId)); }
A následne vo Form1: Kód: void performNavigation(object sender, NavigationArgs e) { MyControlBase control;
switch (e.NavigateToControl) { default: case MyControl.UserControl1: control = new UserControl1(); break; case MyControl.UserControl2: control = new UserControl2(e.EntityId); break; }
ChangeControlTo(control); }
A teraz si len upravíš/vytvoríš konštruktor v UserControl2, aby prijal argument typu "int" (alebo iný/iné, podľa potreby)
_________________ C#, PHP, ... |
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 18.03.2015 15:01 | |
|
Oukej super som spojná ďakujem veľmi pekne
|
|
Registrovaný: 01.09.14 Prihlásený: 28.11.15 Príspevky: 22 Témy: 6 | Napísal autor témy Mirusena: 13.04.2015 11:25 | |
|
Ak sa môžem ešte k tejto téme opýtať... dajú sa prenášať údaje z iného formulára napr. MainForm ktorý má klasickú triedu public partial class MainForm : Form preniesť údaje to napr. UserControl2?
|
|
Registrovaný: 24.01.08 Prihlásený: 13.09.17 Príspevky: 14572 Témy: 66 Bydlisko: Žilina |
V akom zmysle by si ich chcela preniesť? Jeden spôsob je napr pri inicializácii tak, že ich pošleš ako parametre pre konštruktor.
_________________ C#, PHP, ... |
|
| Stránka: 1 z 1
| [ Príspevkov: 16 ] | |
| Nemôžete zakladať nové témy v tomto fóre Nemôžete odpovedať na témy v tomto fóre Nemôžete upravovať svoje príspevky v tomto fóre Nemôžete mazať svoje príspevky v tomto fóre
|
|