簡體   English   中英

如何使實例事件起作用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM