C#, WPF 및 MVVM을 사용한 토스트 알림
Published: 2023-12-01 12:02:41

데스크톱 [알림이](https://www.pubnub.com/use-case/alerts-and-push-notifications/) 실시간 [이벤트 기반](https://www.pubnub.com/guides/event-driven-architecture/) 앱에서 필수적인 기능이 되었다는 사실을 알고 계셨나요? 웹 서비스는 백엔드 신호 또는 다른 사용자의 메시지가 발생하면 사용자에게 알려야 합니다.

소프트웨어 엔지니어 또는 풀스택 소프트웨어 개발자가 **C#** 및 **WPF**, **Windows Forms** 또는 **UWP를** 사용하여 Windows 데스크톱 애플리케이션을 구축하려는 경우 이 가이드는 **MVVM 디자인 패턴으로** 데스크톱 푸시 알림을 위한 **프론트엔드 및 백엔드 코드를** 구축하는 과정을 안내합니다.

여기서 가장 중요한 것은 클라이언트 또는 서버가 전 세계 어디서든 원하는 수의 디바이스, 웹 앱, 모바일 앱에 실시간 신호를 보낼 수 있는 **PubNub의** [**실시간 메시징 API입니다**](https://www.pubnub.com/docs/channels/overview).

**토스트 알림에 필요한 프로그래밍 언어 개요**
---------------------------

이 튜토리얼에서는 다양한 코딩 및 알고리즘 언어를 사용할 것입니다. 먼저 이러한 프로그래머 언어에 대한 간략한 정의를 내린 다음 워크플로 프로세스를 살펴보겠습니다.

**WPF란 무엇인가요?**
---------------

지금부터 함께 살펴볼 코드 예제는 [Windows 프레젠테이션 파운데이션](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/getting-started/introduction-to-wpf-in-vs?view=netframeworkdesktop-4.8) 또는 WPF를 사용하여 작성되었습니다. 지난 10년 동안 WPF는 **C# 및 .NET Framework를** 사용하여 Windows 데스크톱 웹 앱을 개발하는 데 가장 적합한 하위 시스템으로 자리 잡았습니다. 사용자 인터페이스 개발을 위해 [XAML을](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/fundamentals/xaml?view=netdesktop-5.0) 사용하고 모든 보기에 C# [코드 비하인드를](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/code-behind-and-xaml-in-wpf?view=netframeworkdesktop-4.8) 사용한다는 점에서 Windows Forms와 유사합니다.

**빠른 팁:**

이 튜토리얼에서는 MVVM 패턴을 사용할 것이므로 가능한 한 많은 코드를 코드 비하인드 외부에 유지하려고 합니다. 따라서 일반적으로 코드 비하인드 클래스에 표시되는 코드는 **뷰 모델 클래스로 이동합니다**.

**MVVM 아키텍처란 무엇인가요?**
---------------------

**모델-뷰-뷰모델** 또는 MVVM은 사용자 대면 애플리케이션에서 UI 개발과 백엔드 개발을 **분리하기** 위한 디자인 패턴입니다. 이 패턴을 구성하는 **세 가지 구성 요소가** 있습니다.

### WPFApps의 구성 요소는 무엇인가요?

WPFapps의 구성 요소는 다음과 같습니다:

-   뷰 - [XAML 및 코드 비하인드](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/code-behind-and-xaml-in-wpf?view=netframeworkdesktop-4.8)
    
-   ViewModels - 상태 관리 및 모델과 뷰 사이를 이동하는 데이터 제어를 위한 C# 코드.
    
-   모델 - C# 클래스, 데이터 저장소, 비즈니스 로직.
    

![](https://images.ctfassets.net/3prze68gbwl1/655JWYGQsi4tlNkqAhlEYq/197b20ffa25e393fc71d3959804c5d13/pubnub-mvvm-diagram.png)

**C# 데스크톱 알림**
--------------

OS 인식 알림을 위한 Windows 데스크톱 솔루션은 **토스트 알림** 클래스입니다. 토스트 알림은 Windows UI 알림 클래스에 통합되어 있습니다.

### Toast 알림이란 무엇인가요?

이 예에서는 토스트 알림을 사용하겠습니다. 토스트 알림은 자동으로 표시되고 만료되도록 프로그래밍된 작은 팝업입니다. 일반적으로 눈에 잘 띄지 않으며 사용자의 어떤 조치도 필요하지 않습니다. 또한 사용자 활동을 중단시키지 않습니다.

이러한 유형의 자동 푸시 알림은 데스크톱 팝업에 이상적입니다. 그러나 WPF를 사용한 토스트에 대한 지원은 많지 않습니다.

#### **토스트 알림 전문가 팁:**

이 시나리오의 해결 방법은 자체 토스트 데스크톱 알림 사용자 인터페이스를 구축하여 WPFapp에 알림을 포함할 수 있도록 하는 것입니다. 이와 같은 알림은 ViewModel 코드의 기존 C# 이벤트를 사용하여 언제든지 **트리거할** 수 있습니다.

![](https://images.ctfassets.net/3prze68gbwl1/5xBfgEWMPTg4WpQKODQXXq/080ec85b78673760b19f4091be8f608d/pubnub-wpf-notification.png)

우리가 함께 빌드할 예제는 C# 알림이 있는 WPFapp입니다.

버튼이 하나 있는 **부모 창이 하나** 있을 것입니다. 버튼을 클릭하면 **JSON 데이터를** 네트워크에 게시하는 PubNub [게시가](https://www.pubnub.com/docs/sdks/c-sharp/) 트리거됩니다. 애플리케이션은 또한 게시 코드와 **동일한 채널 및 API 키** (무료 [PubNubAPI 키](https://dashboard.pubnub.com/signup))를 사용하여 PubNub에 **구독합니다**.

PubNub 구독 코드는 새 메시지가 게시될 때마다 데스크톱에 팝업 푸시 알림을 생성하는 **C# 이벤트를** 트리거합니다. PubNub 메시지의 지연 시간은 게시자와 구독자 거리에 관계없이 **일반적으로 80~100밀리초입니다**.

![](https://images.ctfassets.net/3prze68gbwl1/3867ZSWtcQs2csl35ZvUzr/5b32af712a7a3656089dd5d837f4ad74/pubnub-desktop-notification.png)

PubNub에는 **70개** 이상의 **클라이언트** [**SDK가**](https://www.pubnub.com/docs/sdks) 있으므로 인터넷이 가능한 모든 디바이스를 이 다이어그램으로 교체할 수 있습니다.

C# 및 MVVM을 사용한 WPFTutorial 알림 튜토리얼 프로젝트
---------------------------------------

우리는 자체 C# 알림 앱을 구축하여 PubNub 메시징의 힘과 WPF 데스크톱 알림 솔루션을 시연해 보겠습니다. 다음은 MVVM 프로젝트의 파일 구조입니다:

![](https://images.ctfassets.net/3prze68gbwl1/FfGomoqHd2m9ZGyqYvFQS/dcd2e6ffe9856e1842f7b227573db292/wpf-pubnub-project.png)

_이 튜토리얼에서 참조하는 모든 코드는_ [**_GitHub에서_**](https://github.com/ajb413/wpf-pubnub-desktop-notifications)**_오픈 소스로 제공됩니다_** _._

_앱을 실행하려면_ **_평생 무료로_** 제공되는[**_PubNubAPI 키를_**](https://dashboard.pubnub.com/signup) 받아야 합니다_._

소스 코드에 **게시 및 구독 키를** 반드시 **추가하세요**!

**MVVM으로 시작하는 데스크톱 알림 빌드하기**
----------------------------

1\. 처음부터 시작하는 경우 오픈비주얼**스튜디오**[(무료](https://visualstudio.microsoft.com/vs/community/))를 실행하고 새 **WPFweb**애플리케이션을 만듭니다. **파일 -> 새로 만들기 -> 프로젝트를 클릭합니다**.

![](https://images.ctfassets.net/3prze68gbwl1/Cy9BHqBZ6O23j8ntXQ5xG/cd1c8e30743790662c6639dcf7d44116/wpf-new-project-1.png)

2\. **솔루션 탐색기에서** 새 프로젝트 파일을 마우스 오른쪽 버튼으로 클릭하고 **NuGet 패키지 관리를** 클릭합니다. 계속하려면 **PubNub를 설치해야** 합니다.

![](https://images.ctfassets.net/3prze68gbwl1/33PqCdHI6MLEgUWfIqjKec/eb638d0eb4b331ea3efd210d13eaed9c/install-pubnub-sdk-csharp.png)

3\. 3. 이전 **스크린샷에서** 참조한 것처럼 **프로젝트의 루트에** 폴더를 생성합니다. 이 폴더는 **모델, 뷰, 뷰모델입니다**. View 폴더에 **메인 창** 과 **알림 창이라는** 두 개의 새 XAML 창을 만듭니다.

**XAML로 알림 빌드 계속하기**
--------------------

다음은 생성한 2개의 보기 파일에 대한 XAML입니다. 이렇게 하면 부모 창과 알림 창의 **UI가 만들어집니다**.

MainWindow.xaml

<Window x:Class="WPF\_PubNub.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:WPF\_PubNub.VM" xmlns:local="clr-namespace:WPF\_PubNub" mc:Ignorable="d"        
  
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" Title="{Binding WindowName}" Height="300" Width="400"> <Window.DataContext> <vm:PubNubVM /> </Window.DataContext> <i:Interaction.Triggers> <i:EventTrigger EventName="Loaded"> <ei:CallMethodAction TargetObject="{Binding}"" MethodName="MainWindowLoaded"/> </i:EventTrigger> </i:Interaction.Triggers> <!--Loaded="{Binding OnWindowLoaded}"--> <Grid > <StackPanel Name="stackPanel2" Grid.Column="1" Grid.Row="0" Background="White" > <Border CornerRadius="5" BorderBrush="Gray" BorderThickness="2" HorizontalAlignment="Center" > <Button Width="{Binding ButtonWidth}" 
                Height="{Binding ButtonHeight}" Content="{Binding ButtonContent}" Background="#FFF3F0F0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:CallMethodAction TargetObject="{Binding}"" MethodName="PublishMessage"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Border> </StackPanel> </Grid> </Window>

**NotificationWindow.xaml**

<Window x:Class="Toast.NotificationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" WindowStyle="None" 
        Height="116.783" Width="319.93" Background="#FF110505" > <Grid> <Grid RenderTransformOrigin="0,1" > <!-- Animation --> <Grid.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"> <SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/> <SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/> <SplineDoubleKeyFrame KeyTime="0:0:4" Value="0"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </Grid.Triggers> <Grid.RenderTransform> <ScaleTransform ScaleY="1" /> </Grid.RenderTransform> <!-- 알림 영역 --> <Border BorderThickness="1" Margin="0,0,0,10" Background="#FF17161F" BorderBrush="Black" CornerRadius="10"> <StackPanel Margin="20,9"> <TextBlock TextWrapping="Wrap" Margin="21,5,23,5" x.:Name="NotifText" Foreground="White" Background="Black" Height="75"/> </StackPanel> </Border> <이미지 가로줄="왼쪽" 높이="37" 세로줄="상단" 폭="42" Source="iconMail.JPG" Margin="0,16,0,0"/> </Grid> <Button BorderThickness="0" HorizontalAlignment="Left" Margin="270,0,0,0" Click="Button\_Click\_Close" VerticalAlignment="Top" Background="{x:Null}" Width="42" Height="43"> <이미지 소스="CloseBtn.JPG" Height="39" Width="28" /> </Button> </Grid> </Window>

### C# 알림 창 코드 예시

다음은 [알림 창에](https://github.com/ajb413/wpf-pubnub-desktop-notifications/blob/master/WPF_PubNub/View/NotificationWindow.xaml.cs) 대한 **C# 코드 비하인드** 코드입니다. 모든 코드는 UI에 따라 다릅니다. "토스트" 알림과 비슷하게 만들어야 합니다.

using System; using System.Windows; using System.Windows.Threading; namespace Toast { /// <summary> /// NotificationWindow의 인터랙션 로직.xaml /// </summary> public partial class NotificationWindow : Window { public NotificationWindow() { InitializeComponent(); Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => { var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice; var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom)); Left = corner.X - 실제 폭; Top = corner.Y - 실제 높이; })); } //Close the notification window private void Button\_Click\_Close(object sender, RoutedEventArgs e) { Close(); } } }

**C#, WPF 및 MVVM 알림을 빌드하는 마지막 단계**
----------------------------------

1.  ViewModel 폴더에서 **모델 코드와** **뷰 코드** 사이의 매개체 역할을 하는 **PubNubVM.cs** 클래스를 만듭니다. 해당 파일의 코드는 [여기에서 찾을 수 있습니다](https://github.com/ajb413/wpf-pubnub-desktop-notifications/blob/master/WPF_PubNub/ViewModel/PubNubVM.cs).
    
2.  Model 폴더에서 PubNub 게시/구독 API와 상호 작용할 **PubNubHelper.cs** 클래스를 생성합니다. **PubNub 초기화 코드에** **무료** [**PubNubAPI 키를**](https://dashboard.pubnub.com/signup) **입력해야** 합니다.
    
3.  파일에서 "\_\_YOUR\_PUBNUB\_PUBLISH\_KEY\_HERE\_\_" 및 "\_\_YOUR\_PUBNUB\_SUBSCRIBE\_KEY\_HERE\_\_"를 볼 수 있습니다. 해당 문자열 리터럴을 키로 바꿉니다.
    

using Newtonsoft.Json; using PubnubApi; using System; using System.Windows; using Toast; 네임스페이스 WPF\_PubNub.Model { public class PubNubHelper { Pubnub pubnub; private 읽기 전용 문자열 ChannelName = "win-notification";
        public void Init() { //Init PNConfiguration pnConfiguration = new PNConfiguration { PublishKey = "\_\_YOUR\_PUBNUB\_PUBLISH\_KEY\_HERE\_\_", SubscribeKey = "\_\_YOUR\_PUBNUB\_SUBSCRIBE\_KEY\_HERE\_\_", Secure = true }; pubnub = new Pubnub(pnConfiguration); //Subscribe pubnub.Subscribe<string>() .Channels(new string\[\] { ChannelName }) .WithPresence() .Execute(); } //Publish a message public void Publish() { JsonMsg Person = new JsonMsg { Name = "John Doe", Description = "Description", Date = DateTime.Now.ToString() }; //Convert to string string arrayMessage = JsonConvert.SerializeObject(Person); pubnub.Publish() .Channel(ChannelName) .Message(arrayMessage) .Async(new PNPublishResultExt((결과, 상태) => {})); } //채널 수신 public void Listen() { SubscribeCallbackExt listenerSubscribeCallack = new SubscribeCallbackExt( (pubnubObj, message) => { //Call 알림 창을 UI 스레드에서 호출합니다 Application.Current.Dispatcher.Invoke(new Action(() => { // 메시지를 WIN-10 토스트와 같은 WPF 창 메시지로 표시 NotificationWindow ts = new NotificationWindow(); // 메시지를 JSON으로 변환 JsonMsg bsObj = JsonConvert.DeserializeObject<JsonMsg>(message.Message.ToString()); string messageBoxText = "Name: " + bsObj.Name + Environment.NewLine + "설명: " + bsObj.Description + Environment.NewLine + "Date: " + bsObj.Date; ts.NotifText.Text = messageBoxText; ts.Show(); })); }, (pubnubObj, presence) => { // 들어오는 현재 상태 데이터 처리 }, (pubnubObj, status) => { // 반환되는 상태 객체는 항상 구독과 관련이 있지만 // 구독, 하트비트 또는 오류에 대한 정보를 포함할 수 있습니다 // 다른 옵션을 켜려면 PNOperationType을 사용하세요 }); pubnub.AddListener(listenerSubscribeCallack); } } }

**프로 팁: Model 폴더에는** [**여기에서 찾을 수 있는**](https://github.com/ajb413/wpf-pubnub-desktop-notifications/blob/master/WPF_PubNub/Model/JsonMsg.cs)**JsonMsg.cs 클래스도 필요합니다** **.** [**WPF 프로젝트 파일에서**](https://github.com/ajb413/wpf-pubnub-desktop-notifications/blob/master/WPF_PubNub/WPF_PubNub.csproj) **참조되는 모든 NuGet 패키지를 추가해야** 합니다**.** [**보기 폴더에**](https://github.com/ajb413/wpf-pubnub-desktop-notifications/tree/master/WPF_PubNub/View) **대한 JPG 이미지 파일도 있습니다** **. 이러한 이미지는 사용자 지정한 알림 창에 나타납니다. 프로젝트 View 폴더에 추가해야 합니다.**

4\. 프로젝트를 실행하세요! "알림 창 트리거" 버튼을 클릭합니다. 바탕화면 오른쪽 하단에 사용자 정의 알림이 나타납니다! 이 알림은 PubNub에서 제공하므로 여러 컴퓨터에서 이 애플리케이션을 실행하는 경우 개별 버튼을 클릭할 때마다 모든 컴퓨터에 알림이 표시됩니다.

![](https://images.ctfassets.net/3prze68gbwl1/6uxw74cdFfaWHFIVIeT1a/ab14d1b074bda88a5d335a8069df95bc/pubnub-wpf-window.png)

다른 [PubNubSDK와](https://www.pubnub.com/docs/sdks) 클라이언트 기기를 사용하면 알림 시스템은 언어/기기에 구애받지 않습니다.

### **데스크톱 토스트 알림 시작하기**

이 데스크톱 알림 패턴은 사용자 경험을 개선하기 위한 사용자 지정 푸시 알림을 위해 수정할 수 있습니다. 여러 채널을 사용하거나 [액세스 관리자를](https://www.pubnub.com/docs/security/access-control) 사용하여 특정 채널을 읽고 쓸 수 있는 사용자를 보호할 수 있습니다.

더 많은 C# 코드 예제를 보려면 [devrel@pubnub.com](mailto:devrel@pubnub.com) 으로 문의하거나 앱 개발 속도를 높이는 데 도움이 되는 [문서](https://www.pubnub.com/docs) 및 [개발자 리소스를](https://www.pubnub.com/developers/) 확인하세요!

펍넙이 어떤 도움을 줄 수 있나요?
===================

이 문서는 원래 [PubNub.com에](https://pubnub.com/blog/c-sharp-desktop-notifications-wpf-mvvm/) 게시되었습니다.

저희 플랫폼은 개발자가 웹 앱, 모바일 앱, IoT 디바이스를 위한 실시간 인터랙티브를 구축, 제공, 관리할 수 있도록 지원합니다.

저희 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 전 세계 15개 이상의 PoP가 8억 명의 월간 활성 사용자를 지원하고 99.999%의 안정성을 제공하므로 중단, 동시 접속자 수 제한, 트래픽 급증으로 인한 지연 시간 문제를 걱정할 필요가 없습니다.

PubNub 체험하기
-----------

[라이브 투어를](https://www.pubnub.com/tour/introduction/) 통해 5분 이내에 모든 PubNub 기반 앱의 필수 개념을 이해하세요.

설정하기
----

PubNub [계정에](https://admin.pubnub.com/signup/) 가입하여 PubNub 키에 무료로 즉시 액세스하세요.

시작하기
----

사용 사례나 [SDK에](https://www.pubnub.com/docs) 관계없이 [PubNub 문서를](https://www.pubnub.com/docs) 통해 바로 시작하고 실행할 수 있습니다.