2017-08-12 17 views
-1

私はC#とフォームの初心者です。現在の時間をさまざまな形式で書き込むウィンドウを作成することです。 しかし、私は別のクラスからフォームの別のラベルにアクセスしようとしています。複数のクラスからフォームのラベルにアクセスするにはどうすればよいですか?

レイアウトは次のようになります。 はclocks layout

だから、今の私は、標準クロック、バイナリで時間を書き込みクロックと文字との時間をアウト呪文クロックをしたいと思います。

私がやりたかったのは、必要なものを計算し、何を表示するかを教えるクラスを作成することでした。

は、だから私は、main関数でのProgram.csでフォームを作成しました:それはすでにForm1の(これも一部であるIドンを開始し、いくつかの事前生成されたコードを持っているよう

Form1 myForm = new Form1(); 

これは不要だったかもしれません「トンが本当に取得は、それがインスタンス化する必要はありません):

using System; 
using System.Windows.Forms; 

namespace Clocks 
{ 
    public class NormalClock 
    { 
     public NormalClock() 
     { 
      myForm.lNormalClock.Text = DateTime.Now.ToLongTimeString(); 
     } 
    } 
} 
:私は通常のクロッククラスで試してみました何

Application.Run(new Form1()); 

ただし、フォームのラベルにアクセスできませんでした。

私の質問はこれです:どのように私は別のクラスから1つのフォームの異なるラベルにアクセスするのですか?

ありがとうございました!

+0

どこから(どのクラス) 'Form1'から' NormalClock'をインスタンス化していますか? – Fruchtzwerg

+0

私はいくつかの変更を加え、Program.csでこれをやろうとしましたが、NormalClockはmyFormのラベルにアクセスできません。 – pwndemic

+0

私はいくつかの変更を加えましたが、今はForm1.csにあります。ちょっとエレガントに見える – pwndemic

答えて

1

フォームにアクセスする機会がある場合は、フォーム(myform)のインスタンスを参照する必要がありますが、変更しない限りデフォルトでは保護されているかプライベートであるため、できませんあなたのアクセス修飾子を変更しない限り、それはとにかくです。それはベストアイデアではありません。

コンストラクタでその何かを渡すために何か(依存関係)に依存する任意のクラスを作成するのが最善の方法です。 あなたのために、ラベルのインスタンスをクロッククラスに渡します。

namespace Clocks 
    { 
     public class NormalClock 
     { 
      private Label label; 

      public NormalClock(Label label) 
      { 
       if(label == null) 
        throw new ArgumentNullReferenceException("label"); 

       this.label = label; 
       label.Text = DateTime.Now.ToLongTimeString(); 
      } 
     } 
    } 
+0

ありがとう、それはうまくいった! – pwndemic

0

時計にフォームを知らせるのは良い考えではないと思います。時計は物事を形作るのではなく時計のことをするべきです。

問題を解決する方法はいくつかあります。まず、時計はどのように動くのですか?ティックイベントを生成するタイマーが必要です。どちらかのタイマーがフォームにあります。次に、時計は現在の時刻のみを読み込み、時刻を表す文字列を返します。フォームは、この文字列のクロックを要求します。

時計のアイデアをよりよく実現している別の方法は、時計の内側にタイマーを置くことです。今、タイマーはフォームに時間をどのように伝えますか?再び、私は2つの可能性を見ます。時計自体がイベントを公開し、イベント引数として時刻文字列を提供するか、時計が文字列をフォームに書き込むかのいずれかです。しかし、私たちは上記のように後者を望んでいません。

異なるタイプのクロックを作成したいので、最初に時間ベースの文字列をフォーマットする以外のすべてを行うクロックベースクラスを作成します。基本クラスから派生したクラスは、異なる種類のタイムストリングを提供します。

abstract class ClockBase 
{ 
    private Timer _timer = new Timer(); // Create the timer. 

    public event EventHandler<ClockTickEventArgs> Tick; 

    public ClockBase() 
    { 
     _timer.Tick += Timer_Tick; // Subscribe to timer tick event. 
     _timer.Interval = 1000; // Let the clock tick every 1000 ms. 
     _timer.Start(); // Start the timer. 
    } 

    private void Timer_Tick(object sender, EventArgs e) 
    { 
     string timeString = FormatTime(DateTime.Now); // Format the current date time. 
     Tick?.Invoke(this, new ClockTickEventArgs(timeString)); // Fire the Tick event. 
    } 

    // This will be implemented by concrete clocks. 
    protected abstract string FormatTime(DateTime time); 
} 

通常のクロックがClockBaseから派生し、時間をフォーマットする方法を実装しています。

class NormalClock : ClockBase 
{ 
    protected override string FormatTime(DateTime time) 
    { 
     return time.ToString("hh:mm:ss"); 
    } 
} 

[次のないフォーム:クロックティックイベントの引数として使用されるクラス:

public partial class frmClock : Form 
{ 
    private ClockBase _clock; 

    public frmClock() 
    { 
     InitializeComponent(); 
     _clock = new NormalClock(); // Create a normal clock. 
     _clock.Tick += Clock_Tick; // Subscribe to the clock Tick event. 
    } 

    private void Clock_Tick(object sender, ClockTickEventArgs e) 
    { 
     lblTime.Text = e.TimeString; // Set the label text. 
    } 
} 

我々はもう一つ必要

class ClockTickEventArgs : EventArgs 
{ 
    public ClockTickEventArgs(string timeString) 
    { 
     this.TimeString = timeString; 
    } 

    public string TimeString { get; private set; } 
} 

を今すぐクロックはクロックのことを行いますフォームは物事を表示します。

関連する問題