[英]How to make event of instance work?
我正在嘗試使用Windows窗體實現裝飾器模式,並在此處遇到一些問題。 當我調用以前裝飾過的實例的事件時,部分無法正常工作,我也不知道為什么。 無效的部分包括我實現的Windows.Forms.Form的操作,但Console.WriteLine可以完美地工作。 您可以在下面測試我的代碼,但是需要在桌面上使用11.txt文件(或更改路徑)才能使其正常工作;
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);
}
}
例如
public virtual void ReadFile(Object source, EventArgs e)
{
Text = "123"; //doesn't work in decorator chain
Console.WriteLine("works"); //works
}
這是因為txtBox
是一個實例字段,並且不會在裝飾器“鏈”中的各個類之間共享。 如果您更改聲明,那么它是靜態的,例如:
public static TextBox txtBox;
那么您將觀察到可能接近預期的行為。 我並不是說這是首選的解決方案,只是說明了問題所在。
將表示和行為分開可能會更好。 這將創建一個可以說是更清潔的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.