Det kan du løse på flere måder: Den nemme er smid instancen af UserControl 1 ind i UserControl 2 og eksekver læsning. Den gode er med events Den fine er med delegates
public class InputData { public event EventHandler DataChanged;
public UserChangesSomeDataFoo() {
} public void OnDataChanged() { if(this.InputData != null) //her chekkes om nogle subscriber til den, hvis man rejser en event uden dette check og der ikke findes nogen subscriber vil det give en null exception this.InputData(this, EventArgs.Empty); // det her er totalt basic.. du kan uden videre også medsende argumenter til subscriberen, men vi holder det simpelt lige pt :) } ... ...
}
Din ReadData må nødvendigvis have en metode du kan trigge for at læse indholdet i Xml'en...
public class ReadData { public ReadXml() { //do something... } }
UserControls har i sagens natur en Main, hvor der er tilknyttet. I Main instancierer du:
class Main { var usrCtrlInput = new InputData();
//til denne findes der nu en event: usrCtrlInput.DataChanged += InputDataChanged;
void InputDataChanged(object sender, EventArgs e) { var readData = new ReadData() readData.ReadXml(); } }
Havde sat denne inden i en anden event void InputDataChanged(object sender, EventArgs e) { var readData = new ReadData(); readData.ReadXml(); }
:p
Men det fungere bare stadig ikke!?
Når jeg via den kontrol som skal læse xml filen åbner den kontrol der skal tilføje til xml filen, så burde kontrollen der læser xml filen jo nu opdatere sig? Men det gør den først hvis jeg lukke programmet og åbner det igen :(
Jeg bruger nedenfor kode til at tilføje til min xml fil
XDocument doc = XDocument.Load(xmlFile);
doc.Root.Add(new XElement("Entry", new XAttribute("id", DateTime.Now.ToString().Replace("-", "").Replace(":", "").Replace(";", "").Replace(" ", "")), new XElement("Date", pro.dateSubmitted), new XElement("Name", pro.Name), new XElement("Description", pro.Description), new XElement("Website", pro.website), new XElement("Content", pro.Content) ) );
} public void OnDataChanged() { if(this.InputData != null) //her chekkes om nogle subscriber til den, hvis man rejser en event uden dette check og der ikke findes nogen subscriber vil det give en null exception this.InputData(this, EventArgs.Empty); // det her er totalt basic.. du kan uden videre også medsende argumenter til subscriberen, men vi holder det simpelt lige pt :) }
Jo jo.. ..Foo er bare for at vise en metode, vidste ikke hvad du kaldte den :)
Kan godt se fejlen her... jeg fik måske skrevet for hurtigt sidst.
Der skal stå: public void OnDataChanged() { if(this.DataChanged != null) this.DataChanged(this, EventArgs.Empty); }
Og så kalder du OnDataChanged efter doc.Save(xmlFile);
Jeg troede ovenstående var rettet en gang?
Sæt et breakpoint i . void InputDataChanged(object sender, EventArgs e) { var readData = new ReadData(); readData.ReadXml(); } Og se om den bliver trigget korrekt :)
Det er sjovt. For jeg har prøvet at fjerne alt det som sker i den event der tilføjer til xml filen og bare skjule en kontrol i den user control som åbner denne kontrol. Men uanset hvad så, sker ændringerne først når jeg lukker den første kontrol og åbner den igen
Det er ikke forkert at jeg bruger en user coltrol til at åbne en anden med vel?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using xmlConnect;
namespace Pages { /// <summary> /// Interaction logic for submit.xaml /// </summary> public partial class submit : UserControl { public submit() { InitializeComponent(); }
Den usercontrol du har der, den må også eksistere med en mainform korrekt? Hvad hedder den?
Den kode du har bikset sammen der svarer lidt mere til den du sagde du ikke ville ha :), altså mulighed 1, du ville have mulighed 2 og den bygger på en mainform hvori du placerer dine usercontrols, så hvad hedder din mainform? Og hvor placerer du dine usercontrols?
ManageCodes er en usercontrol, korrekt? som ligger på samme mainform som den submit-form du har postet der, korrekt?
Som jeg ser det instancierer du ManageCodes flere gange nu kender jeg ikke til funktionaliteten i ManageCodes, men umiddelbart er det heri fejlen ligger.
-------------------//Main//-------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using xmlConnect; using Pages; using System.IO; using System.Windows.Media.Animation;
namespace CodeKeeber { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent();
if (File.Exists("user.xml")) { lblLoginHead.Content = "Login"; } else { lblLoginHead.Content = "First time login"; btnLogin.Content = "Create user"; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using xmlConnect; using System.IO;
namespace Pages { /// <summary> /// Interaction logic for ManageCodes.xaml /// </summary> public partial class ManageCodes : UserControl { public ManageCodes() { InitializeComponent();
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using xmlConnect;
namespace Pages { /// <summary> /// Interaction logic for submit.xaml /// </summary> public partial class submit : UserControl { public submit() { InitializeComponent(); }
Min main ligger i et projekt for sig selv kaldet CodeKeeber
Submit og ManageCodes ligger i et andet projekt kaldet Pages
Når man er logget ind instanciere jeg ManageCodes i min Main og tilføjer den som en UserControl, som så læser min xml fil. I min ManageCodes kan man så tilføje data til xml filen, der instanciere jeg så Submit og tilføjer den som en UserControl i min ManageCodes UserControl.
Altså når man så har tilføjet til min xml fil via User kontrollen Submit som instancieres i userkontroll ManageCodes, lukkes den igen af sig selv. Det er så her jeg vil have User kontrollen ManageCodes til at opdatere sig fra xml filen igen, så man kan se ændringerne. (: Men der sker INTET! ikke før jeg lukker min solution og starter den igen. Eller logger ud og ind igen (Altså fjerner mine user kontroller og tilføjer dem igen)
Det ser bare ud som om du har ombyttet publisher med subscriber.
I din submit-class fjerner du InputDataChanged og tilføjer: public event EventHandler DataChanged; public void OnDataChanged() { if (this.DataChanged != null) { this.DataChanged(this, EventArgs.Empty); } }
I class ManageCode private void btnAddCode_Click(object sender, RoutedEventArgs e) { submit sb = new submit(); sb.DataChanged += InputDataChanged(); pnlListOfCodes.Children.Add(sb); } og stadig i samme class, smider du metoden: void InputDataChanged(object sender, EventArgs e) { this.loadXml(); }
I virkeligheden kan man sige at du indirekte beder Managecode om at genindlæse filen, det du gør ved at rejse en event er at alle subscribere vil modtage information om at DataChanged :) , i dit tilfælde har du kun sat en subscriber på nemlig ManageCode så den vil naturligvis modtage publish-eventen :)
Lad os for sjov antage at du har en helt 3. Usercontrol som skal blinke i 3 sekunder når xml'en er ændret, denne 3. UserControl kan du så også opsætte og altså abonnere på events fra Submit-class. Det smarte i sådan et setup er at Submit-klassen ikke behøver vide noget om hvor informationen omkring xml er ændret bliver anvendt. Smart ik :)
Altså det vil sige at faktisk er det min ManageCode-class der subscriper på den eventhandler der ligger i min submit.class?
I så fald så er det jo egentlig ret smart! (: For så kan jeg jo lade alt muligt andet subscripe til den eventhandler der ligger i min submit-class, uden som sådan at skulle tage hensyn til det i min submit-class
Godt du fik det løst og lærte noget nyt undervejs :)
Og jep.. som buzzzz skriver så skla du lave din egen klasse som nedarver fra EventArgs
public class SubmitEventArgs : EventArgs { public ... SomeProperty... {get; set;} osv.... }
og så :
public void OnDataChanged(string someValue) { if (this.DataChanged != null) { var e = new SubmitEventArgs(); e.SomeProperty = someValue; this.DataChanged(this, e); } }
Derfor kan det til tider pisse mig af at ting kræver en default constructor ( Når man bruger den til ORM ) ... da nogen object bare ikke er en skid værd uden data. :-)
mvh
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.