WPF Implementation of Message Center

WPF Implementation of Message Center

This article will explain how to implement a message center based on WPF. For example, common software often receives messages such as 'news' and 'announcements' pushed from the server.

Last updated 5/11/2022 7:31 AM
juster.zhu
4 min read
Category
WPF
Tags
.NET WPF

1. Overview

This article explains how to implement a message center feature based on WPF. For example, in common software, you often receive messages such as "news" or "announcements" pushed from the server. In this case, an analysis of this requirement is needed.

Functional analysis is as follows:

  • Display message content.
  • Add, delete, and batch delete messages.
  • Message classification (notification messages, interactive messages such as those that can jump to a certain link or module within the program).
  • Message handling (accept, delete, ignore).

2. Implementation

  1. Display message content
    Here, the custom control is considered a ListBox. The messages themselves are multiple items, and each item needs to be operated on.
<ListBox
    Grid.Row="1"
    MaxHeight="335"
    Background="{x:Null}"
    BorderThickness="0"
    ItemContainerStyle="{DynamicResource ListBoxItemStyle}"
    ItemsSource="{Binding MessageItem}"
    ScrollViewer.HorizontalScrollBarVisibility="Hidden">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type localModel:MessageItemModel}">
            <Border
                Height="30"
                BorderBrush="#FFBDBDBD"
                BorderThickness="0,0,0,0.6">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*" />
                        <ColumnDefinition Width="40" />
                    </Grid.ColumnDefinitions>
                    <DockPanel>
                        <Label
                            MaxWidth="70"
                            Content="{Binding Path=Name}"
                            Foreground="Red"
                            ToolTip="{Binding Path=Name}" />
                        <Label
                            MaxWidth="130"
                            Content="{Binding Path=Content}"
                            Foreground="White"
                            ToolTip="{Binding Path=Content}" />
                    </DockPanel>
                    <CheckBox
                        Grid.Column="1"
                        FlowDirection="RightToLeft"
                        IsChecked="{Binding Path=CheckBoxState}" />
                </Grid>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
  1. Add, delete, and batch delete messages

    Once the main container is determined, the next step is to customize each message as a ListBoxItem, with specific handling for each message.

    For example:

    • Notification messages: only need a confirm button.
    • Interactive messages: need confirm, delete, and ignore buttons.
<DataTemplate x:Key="SelectedTemplate" DataType="{x:Type localModel:MessageItemModel}">
    <Border BorderBrush="#FFBDBDBD" BorderThickness="0,0,0,0.6">
        <StackPanel>
            <TextBox
                MaxWidth="240"
                MaxHeight="200"
                Padding="0,5,0,0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Background="Transparent"
                BorderThickness="0"
                FontSize="14"
                Foreground="White"
                IsReadOnly="True"
                Text="{Binding Path=Content}"
                TextAlignment="Center"
                TextWrapping="WrapWithOverflow"
                ToolTip="{Binding Path=Content}"
                VerticalScrollBarVisibility="Auto" />
            <StackPanel
                Margin="5,5,5,9"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <Button
                    Width="60"
                    Height="25"
                    Margin="5"
                    Command="{Binding DataContext.ClickAcceptCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
                    CommandParameter="{Binding}"
                    Content="Accept"
                    Style="{StaticResource BlueButtonStyle}"
                    Visibility="{Binding Path=InvitationType, Converter={StaticResource BooleanToVisibilityConverter}}" />
                <Button
                    Width="60"
                    Height="25"
                    Margin="5"
                    Command="{Binding DataContext.ClickRefuseCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
                    CommandParameter="{Binding}"
                    Content="Ignore"
                    Style="{StaticResource BlueButtonStyle}"
                    Visibility="{Binding Path=InvitationType, Converter={StaticResource BooleanToVisibilityConverter}}" />
                <Button
                    Width="60"
                    Height="25"
                    Margin="5"
                    Command="{Binding DataContext.ClickAgreeCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
                    CommandParameter="{Binding}"
                    Content="Confirm"
                    Style="{StaticResource BlueButtonStyle}"
                    Visibility="{Binding Path=NoticeType, Converter={StaticResource BooleanToVisibilityConverter}}" />
            </StackPanel>
        </StackPanel>
    </Border>
</DataTemplate>
  1. Message classification

    Here, it is sufficient to define specific enumerations in the Model layer.

/// <summary>
/// Message processing result
/// </summary>
public enum SysMessageResult
{
    /// <summary>
    /// Unhandled
    /// </summary>
    Unhandled = 0,
    /// <summary>
    /// Processed
    /// </summary>
    Processed = 1
}

/// <summary>
/// Message type
/// </summary>
public enum SysMessageType
{
    /// <summary>
    /// Notification type
    /// </summary>
    NoticeType = 0,
    /// <summary>
    /// Other type
    /// </summary>
    OtherType = 1
}
  1. Message handling

    Message handling refers to the logic for processing message content using the three buttons: "Confirm", "Accept", and "Ignore". If needed, you can modify these according to your requirements. My definition here is as follows:

    • Confirm: Usually handles notification messages. Processing simply removes the item from the message list and does nothing else.
    • Accept: Handles interactive type buttons. Processing removes the item from the message list and triggers other business processing actions.
    • Ignore: Handles all types of messages. It only does not display the message in the UI, but it still exists in the message list, to be processed later when idle.
Keep Exploring

Related Reading

More Articles
Same category / Same tag 9/13/2025

Migration Series from WPF to Avalonia: Why I Must Migrate My WPF Application to Avalonia

In the past few years, our host computer software has mainly been developed using WPF and WinForm . These technologies work well on the Windows platform and have accompanied us from small-scale trial production to the current stage of large-scale delivery. However, with business development and changes in customer requirements, the single Windows technology stack has gradually become a hurdle we must overcome.

Continue Reading
Same category / Same tag 1/26/2025

Implementing Internationalization in WPF Using Custom XML Files

This article details the method of implementing internationalization in WPF applications using custom XML files, including installing the necessary NuGet packages, dynamically retrieving the language list, dynamically switching languages, using translated strings in code and XAML interfaces, and provides a source code link to help developers easily achieve internationalization in WPF applications.

Continue Reading