[C#] WPF 프로그램의 노티바(시스템 트레이) 아이콘 생성


그냥 바로 못한다


현장실습 중 만든 프로그램은 기본적으로 작동중에는 백그라운드에서 돌아야 한다. 라는 조건이 붙는데, 아래 글(2017/02/06 - [Tip/Develop] - [C#] WinForm 프로그램의 노티바(시스템 트레이) 아이콘 생성)과 같은 조건이다. 같은 C#이고, 전에 만들어둔 코드를 그대로 붙혀 두면 될 것이라고 쉽게 생각했었는데, 그게 아니었다. 당장 NotifyIcon 이라는 도구상자 컴포넌트가 없다.


이유를 알아보니, NotifyIcon이라는 컴포넌트는 System.Windows.Forms 안에 포함되어 있는 거고, WPF는 Forms를 Using하지 않으니 바로 사용할 수 없는 것. 간단하게 System.Windows.Forms을 Using하면 되지 않을까 라는 생각을 하지만, 그렇게 할 경우 MessageBox와 같은 System.Windows.Forms와 System.Windows.Controls에 동일하게 존재하는 객체들의 모호성이 생긴다.


결국은 그냥 NotifyIcon 객체를 직접 지시하여 생성해 주고 그 설정을 맞춰주면 된다. 사실 WinForm의 방법과 크게 차이는 없지만, 직접 지시를 해줘야 하는 부분이 있어야 한다는것.


배경이 똑같으니 목적이나 방법 또한 아래 글(2017/02/06 - [Tip/Develop] - [C#] WinForm 프로그램의 노티바(시스템 트레이) 아이콘 생성)과 거히 동일하니 뭘 할 건지는 해당 글을 먼저 보고 오는것을 추천.



그래서 하는 방법


매인 윈도우가 있는 클래스에 전역변수로 NotifyIcon을 직접 생성해 주고, init를 할 때 해당 객체를 적당히 맞춰준다. WinForm에서 생성하는것과는 다른 부분이 바로 이 부분이고, 그 뒤의 부분은 동일. 필요한 상황에 맞는 이벤트나 메서드에 NotifyIcon을 보여주고 창을 숨긴다. NotifyIcon에 더블클릭 이벤트를 걸어주고, 이 이벤트 안에는 NotifyIcon을 숨기고 창을 보이게 하는것.


1. NotifyIcon을 생성하고 설정

 public partial class MainWindow : Window{
    public System.Windows.Forms.NotifyIcon notify;

    public MainWindow(){
        InitializeComponent();
    }
    ...


전역으로 하나 생성해주고,


private void Window_Loaded(object sender, RoutedEventArgs e){
     notify = new System.Windows.Forms.NotifyIcon();
     notify.Icon = Properties.Resources.ico;
     notify.Text = "PLC 통신";
     notify.DoubleClick += Notify_DoubleClick;

     ...
}


Window가 로드될 때 이름과 아이콘, 그리고 이벤트를 지정해 준다. WinForm때와 마찬가지로 아이콘은 지정해주지 않으면 아무리 잘해도 보이지 않으니강조하는 이유는 내가 당해봐서… 꼭 빼먹지 말고 해주자.


2. 창이 숨겨지고 시스템 트레이 아이콘이 보이게

3. 시스템 트레이 아이콘이 숨겨지고 창이 보이게


는 사실 WinForm때와 동일하다. 2번의 경우 창이 닫길때나 숨겨야 할 상황의 메서드에 창을 숨기고 notifyIcon을 보이게 하면 되고, 3번의 경우에는 그 반대. 물론 그렇다고 WinForm의 코드를 그대로 복붙해서는 안된다. 창의 숨김, 보이기가 WinForm과는 다르니까 신경써주자.

 private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        { 
            if(SharedKeyword.isRunning == true)
            {
                notify.Visible = true;
                this.Visibility = Visibility.Collapsed;
                e.Cancel = true;
                return;

            }
private void Notify_DoubleClick(object sender, EventArgs e)
        {
            notify.Visible = false;
            this.Visibility = Visibility.Visible;
        }


Minny_

,

[C#] WinForm 프로그램의 노티바(시스템 트레이) 아이콘 생성



간단한것만…


현장실습 중에 만든 프로그램에서 가장 기본이 되어야 하는것이 작동중에는 백그라운드에서 돌아야 한다.


막 메뉴가 추가되거나, 아이콘이 상태에 따라서 바뀌거나 하는것이 아닌 간단한 정도만 구현하면 됬었다. 그러니까 순전히 프로그램이 작동중일때(미들웨어로써 역활을 하고 있을때) 프로그램 종료를 하면 종료가 되는것이 아닌

  1. 창이 숨겨지고 2. 시스템 트레이(노티바)에 띄워지도록하고 3. 노티바 아이콘을 더블클릭하면 다시 창이 보이며 시스템 트레이(노티바) 아이콘은 없어지도록

하는것.



위의 목적대로 만드는 방법


WinForm 프로그램은 만들기 쉽다. 도구 상자에서 NotifyIcon 을 가져와서, 아이콘과 이름을 지정한 후, 필요한 상황에 맞는 이벤트나 메서드에 NotifyIcon을 보이게 하고 창을 숨기면 된다. NotifyIcon의 더블클릭 이벤트를 생성해주고 이 이벤트 안에는 NotifyIcon을 숨기고 창을 보이게 하면 끝.



1.NotifyIcon을 생성한다


그냥 도구상자에서 찾아 끌어오면 된다. 그리고 해당 콤포넌트의 아이콘과 이름을 지정해준다. 귀찮으니 이름은 기본값으로 놔두었다. 아이콘은 없으면 안된다. 아이콘이 없으면 아무리 잘 해놔도 보이지 않는다. 아무 아이콘이나 대충 끌어와 리소스에 넣고 맞춰주자.


2.창이 숨겨지고 시스템 트레이 아이콘이 보이게

위와 같은 목적으로 하려면 프로그램이 종료되지 않게 해야 하므로, 해당 프로그램의 매인 From에 FormCosing 이벤트를 붙이고, 해당 메서드에 다음과 같이 작성하면 된다.


private void MoisturmMeasurmentProgram_FormClosing(object sender, FormClosingEventArgs e){
        if (!btnStart.Enabled)
        {
            e.Cancel = true;
            notifyIcon1.Visible = true;
            this.Visible = false;
            return;
        }
    }


물론 상황에 따라 저 if안에 검사할 조건을 바꿔야 한다. 나 같은 경우는 btnStart라는 버튼을 활성화, 비활성화 하는것에 따라 프로그램의 작동 상황을 구분하니 이렇게 한 것이고… 물론 이렇게 하면 안된다!

FromClosing 이벤트를 취소하기 위해 e.Cancel = true를 하였고, 시스템 트레이(노티바) 아이콘을 보이게 한 후, 이 From을 보이지 않게 한다.


3.시스템 트레이 아이콘이 숨겨지고 창이 보이게

창을 다시 띄우고 싶을때 해당하는 메서드에 동작을 넣어주면 된다. 소제목도 2번과 반대이고 로직또한 2번과 반대이니 어렵지 않다. 나는 간단하게 시스템 트레이 아이콘을 더블클릭하면 해당 동작이 되게 한다. 그러기 위해서는 시스템 트레이(노티바) 아이콘의 더블클릭 이벤트를 붙혀주면 된다.


이벤트 붙이는거야 뭐 속성에서 이벤트를 더블클릭해서 메서드 생성을 해주던지, 직접 코드에서 붙혀주던지 알아서 하면 된다. 아래는 해당 이벤트 코드이다.

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e){
        this.Visible = true;
        this.Activate();
    }



Minny_

,