첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
0.02MB

▶ MainPage.xaml

<Page x:Class="TestProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Grid>
        <RelativePanel
            Margin="100"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch">
            <RelativePanel.Resources>
                <ResourceDictionary>
                    <Style TargetType="Button">
                        <Setter Property="BorderThickness" Value="0"           />
                        <Setter Property="Margin"          Value="0 0 10 0"    />
                        <Setter Property="Background"      Value="Transparent" />
                    </Style>
                    <ResourceDictionary.ThemeDictionaries>
                        <ResourceDictionary x:Key="HighContrast">
                            <StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="SystemColorHighlightColor" />
                        </ResourceDictionary>
                    </ResourceDictionary.ThemeDictionaries>
                </ResourceDictionary>
            </RelativePanel.Resources>
            <Button Name="openFileButton"
                ToolTipService.ToolTip="파일 열기"
                Click="openFileButton_Click">
                <Button.Content>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;" />
                </Button.Content>
            </Button>
            <Button
                RelativePanel.RightOf="openFileButton"
                ToolTipService.ToolTip="파일 저장하기"
                Click="saveFileButton_Click">
                <Button.Content>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74E;" />
                </Button.Content>
            </Button>
            <muxc:DropDownButton Name="fontColorButton"
                RelativePanel.AlignRightWithPanel="True"
                BorderThickness="0" 
                Background="Transparent" 
                ToolTipService.ToolTip="폰트 색상">
                <SymbolIcon Symbol="FontColor" />
                <muxc:DropDownButton.Flyout>
                    <Flyout Placement="Bottom">
                        <VariableSizedWrapGrid
                            Orientation="Horizontal"
                            MaximumRowsOrColumns="3">
                            <VariableSizedWrapGrid.Resources>
                                <Style TargetType="Rectangle">
                                    <Setter Property="Width"  Value="32" />
                                    <Setter Property="Height" Value="32" />
                                </Style>
                                <Style TargetType="Button">
                                    <Setter Property="Padding"   Value="0" />
                                    <Setter Property="MinWidth"  Value="0" />
                                    <Setter Property="MinHeight" Value="0" />
                                    <Setter Property="Margin"    Value="5" />
                                </Style>
                            </VariableSizedWrapGrid.Resources>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Red" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Orange" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Yellow" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Green" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Blue" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Indigo" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Violet" />
                                </Button.Content>
                            </Button>
                            <Button Click="fontColorButton_Click">
                                <Button.Content>
                                    <Rectangle Fill="Gray" />
                                </Button.Content>
                            </Button>
                        </VariableSizedWrapGrid>
                    </Flyout>
                </muxc:DropDownButton.Flyout>
            </muxc:DropDownButton>
            <Button Name="italicButton"
                RelativePanel.LeftOf="fontColorButton"
                Click="italicButton_Click"
                ToolTipService.ToolTip="Italic">
                <Button.Content>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8DB;" />
                </Button.Content>
            </Button>
            <Button
                RelativePanel.LeftOf="italicButton"
                ToolTipService.ToolTip="Bold"
                Click="boldButton_Click">
                <Button.Content>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8DD;" />
                </Button.Content>
            </Button>
            <RichEditBox Name="richEditBox"
                RelativePanel.Below="openFileButton" 
                RelativePanel.AlignLeftWithPanel="True" 
                RelativePanel.AlignRightWithPanel="True" 
                MinWidth="300"
                Height="300"
                GotFocus="richEditBox_GotFocus"
                TextChanged="richEditBox_TextChanged" />
            <StackPanel
                RelativePanel.Below="richEditBox" 
                RelativePanel.AlignLeftWith="richEditBox" 
                Margin="0 10 0 0"
                Orientation="Horizontal">
                <TextBlock
                    VerticalAlignment="Center"
                    Margin="0 0 0 3"
                    Text="검색 문자열 :" />
                <TextBox Name="findTextBox"
                    Margin="10 0 0 0"
                    Width="300"
                    PlaceholderText="검색할 텍스트를 입력해 주시기 바립니다."
                    TextChanged="{x:Bind SetHighlight}" 
                    GotFocus="{x:Bind SetHighlight}" 
                    LostFocus="{x:Bind RemoveHighlight}" />
            </StackPanel>
        </RelativePanel>
    </Grid>
</Page>

 

728x90

 

▶ MainPage.xaml.cs

using System;
using System.Collections.Generic;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.Text;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

namespace TestProject
{
    /// <summary>
    /// 메인 페이지
    /// </summary>
    public sealed partial class MainPage : Page
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 현재 색상
        /// </summary>
        private Color currentColor = Colors.Green;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainPage()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainPage()
        {
            InitializeComponent();

            #region 윈도우 크기를 설정한다.

            double width  = 800d;
            double height = 600d;

            double dpi = (double)DisplayInformation.GetForCurrentView().LogicalDpi;

            ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;

            Size windowSize = new Size(width * 96d / dpi, height * 96d / dpi);

            ApplicationView.PreferredLaunchViewSize = windowSize;

            Window.Current.Activate();

            ApplicationView.GetForCurrentView().TryResizeView(windowSize);

            #endregion
            #region 윈도우 제목을 설정한다.

            ApplicationView.GetForCurrentView().Title = "RichEditBox 엘리먼트 : 커스텀 에디터 사용하기";

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 파일 열기 버튼 클릭시 처리하기 - openFileButton_Click(sender, e)

        /// <summary>
        /// 파일 열기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private async void openFileButton_Click(object sender, RoutedEventArgs e)
        {
            FileOpenPicker fileOpenPicker = new FileOpenPicker
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary
            };

            fileOpenPicker.FileTypeFilter.Add(".rtf");

            StorageFile storageFile = await fileOpenPicker.PickSingleFileAsync();

            if(storageFile != null)
            {
                using(IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
                {
                    this.richEditBox.Document.LoadFromStream(TextSetOptions.FormatRtf, stream);
                }
            }
        }

        #endregion
        #region 파일 저장 버튼 클릭시 처리하기 - saveFileButton_Click(sender, e)

        /// <summary>
        /// 파일 저장 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private async void saveFileButton_Click(object sender, RoutedEventArgs e)
        {
            FileSavePicker fileSavePicker = new FileSavePicker
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary
            };

            fileSavePicker.FileTypeChoices.Add("Rich Text", new List<string>() { ".rtf" });

            fileSavePicker.SuggestedFileName = "New Document";

            StorageFile storageFile = await fileSavePicker.PickSaveFileAsync();

            if(storageFile != null)
            {
                CachedFileManager.DeferUpdates(storageFile);

                using(IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    this.richEditBox.Document.SaveToStream(TextGetOptions.FormatRtf, stream);
                }

                FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(storageFile);

                if(status != FileUpdateStatus.Complete)
                {
                    MessageDialog messageDialog = new MessageDialog($"{storageFile.Name} 파일을 저장할 수 없습니다.");

                    await messageDialog.ShowAsync();
                }
            }
        }

        #endregion
        #region 폰트 색상 버튼 클릭시 처리하기 - fontColorButton_Click(sender, e)

        /// <summary>
        /// 폰트 색상 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void fontColorButton_Click(object sender, RoutedEventArgs e)
        {
            Button    button    = sender as Button;
            Rectangle rectangle = button.Content as Rectangle;
            Color     color     = (rectangle.Fill as SolidColorBrush).Color;

            this.richEditBox.Document.Selection.CharacterFormat.ForegroundColor = color;

            fontColorButton.Flyout.Hide();

            this.richEditBox.Focus(FocusState.Keyboard);

            this.currentColor = color;
        }

        #endregion
        #region 이탤릭체 버튼 클릭시 처리하기 - italicButton_Click(sender, e)

        /// <summary>
        /// 이탤릭체 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void italicButton_Click(object sender, RoutedEventArgs e)
        {
            this.richEditBox.Document.Selection.CharacterFormat.Italic = FormatEffect.Toggle;
        }

        #endregion
        #region 볼드체 버튼 클릭시 처리하기 - boldButton_Click(sender, e)

        /// <summary>
        /// 볼드체 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void boldButton_Click(object sender, RoutedEventArgs e)
        {
            this.richEditBox.Document.Selection.CharacterFormat.Bold = FormatEffect.Toggle;
        }

        #endregion
        #region 리치 편집 박스 포커스 획득시 처리하기 - richEditBox_GotFocus(sender, e)

        /// <summary>
        /// 리치 편집 박스 포커스 획득시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void richEditBox_GotFocus(object sender, RoutedEventArgs e)
        {
            this.richEditBox.Document.GetText(TextGetOptions.UseCrlf, out string currentRawText);
            
            ITextRange textRange = this.richEditBox.Document.GetRange(0, TextConstants.MaxUnitCount);

            SolidColorBrush backgroundBrush = App.Current.Resources["TextControlBackgroundFocused"] as SolidColorBrush;

            if(backgroundBrush != null)
            {
                textRange.CharacterFormat.BackgroundColor = backgroundBrush.Color;
            }
        }

        #endregion
        #region 리치 편집 박스 텍스트 변경시 처리하기 - richEditBox_TextChanged(sender, e)

        /// <summary>
        /// 리치 편집 박스 텍스트 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void richEditBox_TextChanged(object sender, RoutedEventArgs e)
        {
            if(this.richEditBox.Document.Selection.CharacterFormat.ForegroundColor != this.currentColor)
            {
                this.richEditBox.Document.Selection.CharacterFormat.ForegroundColor = this.currentColor;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 하이라이트 설정하기 - SetHighlight()

        /// <summary>
        /// 하이라이트 설정하기
        /// </summary>
        private void SetHighlight()
        {
            RemoveHighlight();

            Color highlightBackgroundColor = (Color)App.Current.Resources["SystemColorHighlightColor"    ];
            Color highlightForegroundColor = (Color)App.Current.Resources["SystemColorHighlightTextColor"];

            string textToFind = this.findTextBox.Text;

            if(textToFind != null)
            {
                ITextRange textRange = this.richEditBox.Document.GetRange(0, 0);

                while(textRange.FindText(textToFind, TextConstants.MaxUnitCount, FindOptions.None) > 0)
                {
                    textRange.CharacterFormat.BackgroundColor = highlightBackgroundColor;
                    textRange.CharacterFormat.ForegroundColor = highlightForegroundColor;
                }
            }
        }

        #endregion
        #region 하이라이트 제거하기 - RemoveHighlight()

        /// <summary>
        /// 하이라이트 제거하기
        /// </summary>
        private void RemoveHighlight()
        {
            ITextRange textRange = this.richEditBox.Document.GetRange(0, TextConstants.MaxUnitCount);

            SolidColorBrush defaultBackgroundBrush = this.richEditBox.Background as SolidColorBrush;
            SolidColorBrush defaultForegroundbrush = this.richEditBox.Foreground as SolidColorBrush;

            textRange.CharacterFormat.BackgroundColor = defaultBackgroundBrush.Color;
            textRange.CharacterFormat.ForegroundColor = defaultForegroundbrush.Color;
        }

        #endregion
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker
TAG , , ,

댓글을 달아 주세요