2016-06-26 8 views
0

Ich versuche Decorator-Muster mit Windows Forms zu implementieren und habe hier einige Fragen. Wenn ich das Ereignis einer zuvor dekorierten Instanz anrufe, funktioniert es teilweise nicht und ich kann nicht herausfinden warum. Teil, der nicht funktioniert, enthält Aktionen mit Windows.Forms.Form, die ich implementiere, aber Console.WriteLine funktioniert perfekt. Sie können meinen Code unten testen, aber Sie benötigen 11.txt Datei auf Ihrem Desktop (oder ändern Sie den Pfad), damit es funktioniert;Wie kann das Ereignis der Instanz funktionieren?

using System.Windows.Forms; 
using System.IO; 
using System; 

class Decorator 
{ 
    class UpgradedStream : Form 
    { 
     public TrackBar trbRead; 
     public Button btnRead; 
     public TextBox txtBox; 

     public UpgradedStream() 
     { 
      this.Width = 600; 
      this.Height = 600; 
      this.Text = "Decorating Stream class"; 

      trbRead = new TrackBar(); 
      trbRead.Width = 300; 
      trbRead.Value = 2; 

      btnRead = new Button(); 
      btnRead.Click += new EventHandler(ReadFile); 
      btnRead.Text = "&Slide bar abowe!"; 
      btnRead.Top = 40; 
      btnRead.Width = 150; 

      txtBox = new TextBox(); ; 
      txtBox.Multiline = true; 
      txtBox.Top = 75; 
      txtBox.Width = 550; 
      txtBox.Height = 450; 
      txtBox.ScrollBars = ScrollBars.Vertical; 

      this.Controls.Add(btnRead); 
      this.Controls.Add(trbRead); 
      this.Controls.Add(txtBox); 
     } 

     public virtual void ReadFile(Object source, EventArgs e) 
     { 
      Text = "123"; //doesn't work in decorator chain 
      Console.WriteLine("works"); //works 
     } 
    } 

    class DecoratedStream : UpgradedStream 
    { 
     public UpgradedStream previous; 
     public FileStream fin = null; 
     public int i, count = 0; 

     public DecoratedStream(UpgradedStream us) 
     { 
      previous = us; 


      fin = new FileStream("11.txt", FileMode.Open); 
     } 

     public override void ReadFile(Object source, EventArgs e) 
     { 
      previous.ReadFile(source, e); 
      try 
      { 
       fin = new FileStream("C:\\Users\\Vitaliy\\Desktop\\11.txt", FileMode.Open); 

       do 
       { 
        count++; 
        i = fin.ReadByte(); 
        if (i != -1) txtBox.Text += (char)i; 
       } while (i != -1 && count < fin.Length * (trbRead.Value * 0.1)); 
      } 
      catch (IOException exc) 
      { 
       txtBox.Text += ("Error Input-Output:\n" + exc.Message); 
      } 
      finally 
      { 
       txtBox.Text += "\r\n"; 
       txtBox.Text += String.Format("WRITED: {0} SYMBOLS\r\n", Convert.ToInt32(fin.Length * (trbRead.Value * 0.1))); 
       txtBox.Text += "\r\n"; 

       if (fin != null) fin.Close(); 
       count = 0; 
      } 
     } 
    } 

    class PasswordForm : Form 
    { 
     private Label lblPassForm; 
     private Button btnPassForm; 
     private TextBox tbxPassForm; 

     public PasswordForm() 
     { 
      this.Text = "Enter password"; 
      lblPassForm = new Label(); 
      lblPassForm.Text = "password - 123"; 

      tbxPassForm = new TextBox(); 
      tbxPassForm.Top = 30; 

      btnPassForm = new Button(); 
      btnPassForm.Text = "&OK"; 
      btnPassForm.Top = 50; 
      btnPassForm.Click += new EventHandler(ClosePassForm); 
      btnPassForm.DialogResult = DialogResult.OK; 

      this.Controls.Add(lblPassForm); 
      this.Controls.Add(tbxPassForm); 
      this.Controls.Add(btnPassForm); 
     } 
     public void ClosePassForm(Object source, EventArgs e) 
     { 
      password = tbxPassForm.Text; 
      this.Close(); 
     } 

     public String password { get; set; } 
    } 

    class AskPassword : UpgradedStream 
    { 
     public PasswordForm PassForm; 

     private string password; 

     protected internal UpgradedStream previous; 

     public AskPassword(UpgradedStream us) 
     { 
      previous = us; 
     } 

     public override void ReadFile(Object source, EventArgs e) 
     { 
      previous.ReadFile(source, e); 

      using (PassForm = new PasswordForm()) 
      { 
       if (PassForm.ShowDialog() == DialogResult.OK) 
       { 
        if (PassForm.password == "123") 
         previous.ReadFile(source, e); 
       } 
      } 
     } 
    } 


    static void Main() 
    { 
     Application.EnableVisualStyles(); 

     UpgradedStream up = new UpgradedStream(); 
     DecoratedStream dk = new DecoratedStream(up); 
     AskPassword ask = new AskPassword(dk); 

     Application.Run(ask); 
    } 
} 

für exapmple

public virtual void ReadFile(Object source, EventArgs e) 
{ 
    Text = "123"; //doesn't work in decorator chain 
    Console.WriteLine("works"); //works 
} 
+0

Was genau funktioniert nicht? Ich kann den Code erfolgreich ausführen, aber ich bin mir nicht sicher, was ich erwarte. –

+0

Ändern Main() wie folgt: Application.Run (dk); Sie sehen Text in TextBox Aber es muss mit Application.Run arbeiten (ask); Auch ich weiß nicht, wie es geht –

Antwort

0

Dies liegt daran, txtBox ein Instanzfeld ist und zwischen den Klassen in Ihrer Dekorateur ‚Kette‘ geteilt. Wenn Sie die Erklärung ändern, so ist, dass es statisch wie:

public static TextBox txtBox; 

dann werden Sie Verhalten beobachten, die näher sein könnte, was Sie erwarten. Ich schlage nicht vor, dass dies die bevorzugte Lösung ist, nur dass es das Problem veranschaulicht.

Sie könnten besser durch Trennung von Präsentation und Verhalten gedient werden. Dies wird zu einer saubereren Lösung führen.

+0

Vielen Dank, ich frage mich, warum VS gab mir keine Warnung oder sogar Fehler –

+0

Ich nehme an, es gibt nichts, vor dem Sie warnen. Das ist das legale Verhalten, das Sie zur Implementierung ausgewählt haben. Es führt nur ein subtiles Problem ein, das Sie lösen müssen. –

+0

Nicht nur ist es nicht "die bevorzugte Lösung", es ist nicht einmal eine Lösung. Es gibt keinen triftigen Grund dafür, dass eine Kontrollinstanz jemals eine statische Variable ist. –

Verwandte Themen