첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.

728x90
반응형
728x170

TestProject.zip
다운로드

▶ CustomEditContainer1.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace TestProject
{
    /// <summary>
    /// 커스텀 편집 컨테이너 1
    /// </summary>
    public class CustomEditContainer1 : ContentControl
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 변경시 이벤트 - EditStateChangedEvent

        /// <summary>
        /// 편집 상태 변경시 이벤트
        /// </summary>
        public static readonly RoutedEvent EditStateChangedEvent = EventManager.RegisterRoutedEvent
        (
            "EditStageChanged",
            RoutingStrategy.Direct,
            typeof(RoutedPropertyChangedEventArgs<bool>),
            typeof(CustomEditContainer1)
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// DependencyProperty
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 속성 - EditStateProperty

        /// <summary>
        /// 편집 상태 속성
        /// </summary>
        public static readonly DependencyProperty EditStateProperty = DependencyProperty.Register
        (
            "EditState",
            typeof(bool),
            typeof(CustomEditContainer1),
            new PropertyMetadata
            (
                false,
                new PropertyChangedCallback(EditStatePropertyChangedCallback)
            )
        );

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 변경시 이벤트 - EditStateChanged

        /// <summary>
        /// 편집 상태 변경시 이벤트
        /// </summary>
        public event RoutedEventHandler EditStateChanged
        {
            add
            {
                AddHandler(EditStateChangedEvent, value);
            }
            remove
            {
                RemoveHandler(EditStateChangedEvent, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 - EditState

        /// <summary>
        /// 편집 상태
        /// </summary>
        public bool EditState
        {
            get
            {
                return (bool)GetValue(EditStateProperty);
            }
            set
            {
                this.SetValue(EditStateProperty, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Static

        #region 생성자 - CustomEditContainer1()

        /// <summary>
        /// 생성자
        /// </summary>
        static CustomEditContainer1()
        {
            EventManager.RegisterClassHandler
            (
                typeof(CustomEditContainer1),
                PreviewMouseRightButtonDownEvent,
                new RoutedEventHandler(ContentControl_PreviewMouseRightButtonDown)
            );
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CustomEditContainer1()

        /// <summary>
        /// 생성자
        /// </summary>
        public CustomEditContainer1() : base()
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Internal

        #region 컨텐트 컨트롤 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기 - ContentControl_PreviewMouseRightButtonDown(sender, e)

        /// <summary>
        /// 컨텐트 컨트롤 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        internal static void ContentControl_PreviewMouseRightButtonDown(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("OnPreviewMouseRightButtonDown 함수 호출전에 호출됩니다.");

            //e.Handled = true;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 편집 상태 속성 변경시 콜백 처리하기 - EditStatePropertyChangedCallback(d, e)

        /// <summary>
        /// 편집 상태 속성 변경시 콜백 처리하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <param name="e">이벤트 인자</param>
        private static void EditStatePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CustomEditContainer1 container = d as CustomEditContainer1;

            if(container != null)
            {
                RoutedPropertyChangedEventArgs<bool> eventArgs = new RoutedPropertyChangedEventArgs<bool>
                (
                    (bool)e.OldValue,
                    (bool)e.NewValue
                );

                eventArgs.RoutedEvent = EditStateChangedEvent;

                container.RaiseEvent(eventArgs);
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Protected

        #region 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기 - OnPreviewMouseRightButtonDown(e)

        /// <summary>
        /// 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnPreviewMouseRightButtonDown(MouseButtonEventArgs e)
        {
            CustomEditContainer1 container = GetContainer(e.Source as DependencyObject);

            if(container != null)
            {
                if(container.EditState)
                {
                    container.EditState = false;
                }
                else
                {
                    container.EditState = true;
                }
            }

            e.Handled = true;

            base.OnPreviewMouseRightButtonDown(e);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 컨테이너 구하기 - GetContainer(d)

        /// <summary>
        /// 컨테이너 구하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <returns>컨테이너</returns>
        private CustomEditContainer1 GetContainer(DependencyObject d)
        {
            if(d == null)
            {
                return null;
            }

            if(d.GetType() == typeof(CustomEditContainer1))
            {
                return d as CustomEditContainer1;
            }
            else
            {
                DependencyObject parent = VisualTreeHelper.GetParent(d);

                if(parent == null)
                {
                    return null;
                }
                else
                {
                    return GetContainer(parent);
                }
            }
        }

        #endregion
    }
}

 

728x90

 

▶ CustomEditContainer2.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace TestProject
{
    /// <summary>
    /// 커스텀 편집 컨테이너 2
    /// </summary>
    public class CustomEditContainer2 : ContentControl
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 변경시 이벤트 - EditStateChangedEvent

        /// <summary>
        /// 편집 상태 변경시 이벤트
        /// </summary>
        public static readonly RoutedEvent EditStateChangedEvent = CustomEditContainer1.EditStateChangedEvent.AddOwner
        (
            typeof(CustomEditContainer2)
        );

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 변경시 이벤트 - EditStateChanged

        /// <summary>
        /// 편집 상태 변경시 이벤트
        /// </summary>
        public event RoutedEventHandler EditStateChanged
        {
            add
            {
                AddHandler(EditStateChangedEvent, value);
            }
            remove
            {
                RemoveHandler(EditStateChangedEvent, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// DependencyProperty
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 속성 - EditStateProperty

        /// <summary>
        /// 편집 상태 속성
        /// </summary>
        public static readonly DependencyProperty EditStateProperty = CustomEditContainer1.EditStateProperty.AddOwner
        (
            typeof(CustomEditContainer2),
            new PropertyMetadata
            (
                false,
                new PropertyChangedCallback(EditStatePropertyChangedCallback)
            )
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 상태 - EditState

        /// <summary>
        /// 편집 상태
        /// </summary>
        public bool EditState
        {
            get
            {
                return (bool)GetValue(EditStateProperty);
            }
            set
            {
                this.SetValue(EditStateProperty, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Static

        #region 생성자 - CustomEditContainer2()

        /// <summary>
        /// 생성자
        /// </summary>
        static CustomEditContainer2()
        {
            EventManager.RegisterClassHandler
            (
                typeof(CustomEditContainer2),
                PreviewMouseRightButtonDownEvent,
                new RoutedEventHandler(CustomEditContainer1.ContentControl_PreviewMouseRightButtonDown)
            );
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 편집 상태 속성 변경시 콜백 처리하기 - EditStatePropertyChangedCallback(d, e)

        /// <summary>
        /// 편집 상태 속성 변경시 콜백 처리하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <param name="e">이벤트 인자</param>
        private static void EditStatePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CustomEditContainer2 container = d as CustomEditContainer2;

            if(container != null)
            {
                RoutedPropertyChangedEventArgs<bool> eventArgs = new RoutedPropertyChangedEventArgs<bool>
                (
                    (bool)e.OldValue,
                    (bool)e.NewValue
                );

                eventArgs.RoutedEvent = EditStateChangedEvent;

                container.RaiseEvent(eventArgs);
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Protected

        #region 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기 - OnPreviewMouseRightButtonDown(e)

        /// <summary>
        /// 프리뷰 마우스 오른쪽 버튼 DOWN 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnPreviewMouseRightButtonDown(MouseButtonEventArgs e)
        {
            CustomEditContainer2 container = GetContainer(e.Source as DependencyObject);

            if(container != null)
            {
                if(container.EditState)
                {
                    container.EditState = false;
                }
                else
                {
                    container.EditState = true;
                }
            }

            e.Handled = true;

            base.OnPreviewMouseLeftButtonDown(e);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 컨테이너 구하기 - GetContainer(d)

        /// <summary>
        /// 컨테이너 구하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <returns>컨테이너</returns>
        private CustomEditContainer2 GetContainer(DependencyObject d)
        {
            if(d == null)
            {
                return null;
            }

            if(d.GetType() == typeof(CustomEditContainer2))
            {
                return d as CustomEditContainer2;
            }
            else
            {
                DependencyObject parent = VisualTreeHelper.GetParent(d);

                if(parent == null)
                {
                    return null;
                }
                else
                {
                    return GetContainer(parent);
                }
            }
        }

        #endregion
    }
}

 

300x250

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject"
    Width="800"
    Height="600"
    Title="MainWindow"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Grid>
        <StackPanel
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <local:CustomEditContainer1 x:Name="customEditContainer1"
                Margin="10">
                <Border
                    BorderBrush="Black"
                    BorderThickness="10"
                    Background="Gold">
                    <Ellipse
                        Width="100"
                        Height="100"
                        Fill="RoyalBlue" />
                </Border>
            </local:CustomEditContainer1>
            <local:CustomEditContainer2 x:Name="customEditContainer2"
                Margin="10">
                <Border
                    BorderBrush="Black"
                    BorderThickness="10"
                    Background="RoyalBlue">
                    <Ellipse
                        Width="100"
                        Height="100"
                        Fill="Gold" />
                </Border>
            </local:CustomEditContainer2>
        </StackPanel>
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System.Windows;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

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

            this.customEditContainer1.EditStateChanged += customEditContainer1_EditStateChanged;
            this.customEditContainer2.EditStateChanged += customEditContainer2_EditStateChanged;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 커스텀 편집 컨테이너 1 편집 상태 변경시 처리하기 - customEditContainer1_EditStateChanged(sender, e)

        /// <summary>
        /// 커스텀 편집 컨테이너 1 편집 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void customEditContainer1_EditStateChanged(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("customEditContainer1 객체의 EditStateChanged 이벤트가 발생했습니다.");
        }

        #endregion
        #region 커스텀 편집 컨테이너 2 편집 상태 변경시 처리하기 - customEditContainer2_EditStateChanged(sender, e)

        /// <summary>
        /// 커스텀 편집 컨테이너 2 편집 상태 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void customEditContainer2_EditStateChanged(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("customEditContainer2 객체의 EditStateChanged 이벤트가 발생했습니다.");
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요