2016-05-24 10 views
1

私は、System.Windows.Forms.Controlから継承するカスタムコントロールを持っており、MouseEnterイベントとMouseLeaveイベントのBackColorプロパティを変更します。私はこれを使ってカスタムボタンクラスを作成します。クリックハンドラがすべてのボタンを含むメインフォームを最小化する1つのボタンを除いて、すべてが効果的です。このボタンをクリックしてフォームを最小化すると、そのボタンのMouseLeaveイベントは発生しません(MouseUp、Clickなど)。カスタムコントロールが最小化時にMouseLeaveイベントを取得しない

問題は、アプリケーションを通常のウィンドウ状態に戻すときに問題が発生します。カスタム最小化ボタンの上にマウスを置くと、MouseEnterイベントは発生しません。ボタンをクリックしないままにすると、私は最終的にMouseLeaveを取得します。メインフォームが最小化されたときに元のMouseLeaveが起動されたことはないので、MouseEnterが可能であるとは思われません。だからあなたが出入りするまでは、すべてが基本的に壊れています。

私はクリックハンドラを手動でOnMouseLeaveを呼び出してみましたが、それは何も変更されませんでしたが、特に重要なのはEventArgsパラメータで何も指定しませんでした。

これを動作させるには何が欠けているのですか?

編集:ここでは完全なプロジェクトです:

https://dl.dropboxusercontent.com/u/32742882/Button.zip

は、問題は、具体的notifyIconに最小化することに関連して、最小限の正常に表示されませんが判明。

編集:コードを追加しています...

public class IconButton : Control 
{ 
    public bool pressed; 

    static readonly public bool boundingBox = false; 
    static readonly Color darkGray = Color.FromArgb(255, 112, 112, 112); 
    static readonly Color mediumGray = Color.FromArgb(255, 145, 145, 145); 
    static readonly Color lightGray = Color.FromArgb(255, 178, 178, 178); 
    static readonly Color hoverColor = Color.FromArgb(255, 209, 226, 242); 
    static readonly Color backgroundColor = boundingBox ? Color.FromArgb(255, 227, 227, 227) : SystemColors.Control; 
    static readonly Color pressColor = Color.FromArgb(255, 180, 212, 244); 
    static readonly Color enabledTextColor = Color.Black; 
    static readonly Color disabledTextColor = mediumGray; 

    public IconButton() 
    { 
    this.BackColor = backgroundColor; 
    this.DoubleBuffered = true; 
    this.Margin = new Padding(2); 
    } 

    protected override void OnMouseEnter(EventArgs e) 
    { 
    if (Enabled) 
    { 
     this.BackColor = hoverColor; 
    } 
    base.OnMouseEnter(e); 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
    this.BackColor = backgroundColor; 
    base.OnMouseLeave(e); 
    } 

    protected override void OnMouseDown(MouseEventArgs e) 
    { 
    if (Enabled) 
    { 
     this.BackColor = pressColor; 
    } 
    base.OnMouseDown(e); 
    } 

    protected override void OnMouseUp(MouseEventArgs e) 
    { 
    if (Enabled) 
    { 
     if (this.ClientRectangle.Contains(e.Location)) 
     { 
     this.BackColor = hoverColor; 
     } 
     else 
     { 
     this.BackColor = backgroundColor; 
     } 
    } 
    base.OnMouseUp(e); 
    } 
} 

FINAL EDIT:

はそう問題はMainForm_SizeChangedハンドラに直接ShowInTaskbar =偽の呼び出しに結ばれました。これは、トラック内のイベント処理を停止して問題を引き起こしたようです。だから代わりに、私は今このラインを250ms延期し、すべてがよく見えます。でも、私は、このクリーナーを作成する方法についての提案を開いている...

private void Form1_SizeChanged(object sender, EventArgs e) 
    { 
     if (WindowState == FormWindowState.Minimized) 
     { 
      notifyIcon.Visible = true; 

      notifyIcon.BalloonTipText = "We got minimized"; 
      notifyIcon.Text = "Minimized"; 

      notifyIcon.ShowBalloonTip(1000); 

      TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

      Task.Delay(250).ContinueWith(_ => { 
       this.ShowInTaskbar = false; 
      }, CancellationToken.None, TaskContinuationOptions.None, scheduler); 
     } 
     else if (WindowState == FormWindowState.Normal) 
     { 
      ShowInTaskbar = true; 
      notifyIcon.Visible = false; 
     } 
    } 
+0

本当に良い理由がない限り、代わりに 'Control'から継承するべきではありません。代わりに' UserControl'を継承してください。 – DonBoitnott

+0

@DonBoitnottなぜですか?私はMicrosoftがカスタムボタンを作成した例を単に追ってきました。あなたが見ることができるように、彼らはコントロールから継承します。 https://msdn.microsoft.com/en-us/library/ms172532(v=vs.90).aspx –

+0

あなたの最初のレッスンは、その例がどれほど悪いか、私の友人です。 'UserControl'は独自のコントロールを作成するのに役立つように設計されています。あなたの肩から少し体重をとります。ここでは、 'Control'から直接継承することで、必要以上に頑張ることができます。 – DonBoitnott

答えて

1

あなたがfalseにShowInTaskbarを設定しているので、あなたの意図は、実際に隠す形態にではありませんそれを最小化する。これを行うには、intercept the minimizing eventに必要なので、このような何かにあなたのコードを変更してみてください:私はForm1_SizeChangedイベントを排除

private void ToggleView() { 
    if (this.Visible) { 
    this.Hide(); 
    notifyIcon.Visible = true; 
    notifyIcon.BalloonTipText = "We got minimized"; 
    notifyIcon.Text = "Minimized"; 
    notifyIcon.ShowBalloonTip(1000); 
    } else { 
    this.Show(); 
    notifyIcon.Visible = false; 
    } 
} 

protected override void WndProc(ref Message m) { 
    const int WM_SYSCOMMAND = 0x0112; 
    const int SC_MINIMIZE = 0xf020; 

    if (m.Msg == WM_SYSCOMMAND) { 
    if (m.WParam.ToInt32() == SC_MINIMIZE) { 
     m.Result = IntPtr.Zero; 
     ToggleView(); 
     return; 
    } 
    } 
    base.WndProc(ref m); 
} 

public void button_click(object sender, EventArgs e) { 
    ToggleView(); 
} 

private void notifyIcon_MouseClick(object sender, MouseEventArgs e) { 
    ToggleView(); 
} 

注意。

-1
private void Form1_Resize (object sender , EventArgs e) 
{ 
    if (WindowState == FormWindowState.Minimized) 
    { 
     // code on minimized 
    } 
    else if(WindowsState == FormWindowState.Maximized) 
    { 
     // code on maximized 
    } 
} 
+0

私はこれをやっており、それが私の元の投稿の情報を得た方法です。最小化が発生したときにMouseLeaveが発生せず、アプリケーションを復元してこのコントロールに戻ると、最初のMouseEnterがありません。その時点から、外へ出てから予定どおりにイベントを再開します。私はポストをコードで更新しますが、それは非常に簡単です。 –

+0

しかし、最小化してもMouseLeaveを発射すべきではありません... MouseLeaveと同じことをする別のイベントハンドラを配置しますが、onMinimizeイベント – ChenChi

+0

私は答えを編集しました – ChenChi

関連する問題