2017年11月23日木曜日

WPF 添付イベント(Attached Event)実装例

添付イベントの実装例を紹介します。

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp3
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        
        private void InputChangedHandler(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("InputChangedHanlder is called.");
        }
    }

    public static class EventHelper
    {
        public static readonly DependencyProperty IsEventRaisingProperty =
            DependencyProperty.RegisterAttached("IsEventRaising",
            typeof(bool),
            typeof(EventHelper),
            new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsEventRaisingChanged)));

        public static bool GetIsEventRaising(DependencyObject sender)
        {
            return (bool)sender.GetValue(IsEventRaisingProperty);
        }

        public static void SetIsEventRaising(DependencyObject sender, bool ier)
        {
            sender.SetValue(IsEventRaisingProperty, ier);
        }

        public static readonly RoutedEvent InputChangedEvent = EventManager.RegisterRoutedEvent(
            "InputChanged",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(EventHelper)
        );

        public static void AddInputChangedHandler(DependencyObject sender, RoutedEventHandler handler)
        {
            UIElement element = sender as UIElement;
            if (element != null)
            {
                element.AddHandler(InputChangedEvent, handler);
            }
        }

        public static void RemoveInputChangedHandler(DependencyObject sender, RoutedEventHandler handler)
        {
            UIElement element = sender as UIElement;
            if (element != null)
            {
                element.RemoveHandler(InputChangedEvent, handler);
            }
        }

        private static void OnIsEventRaisingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as TextBox).TextChanged += (_s, _e) =>
            {
                (sender as TextBox).RaiseEvent(new RoutedEventArgs(InputChangedEvent));
            };
        }
    }
}

MainWindow.xaml
<Window
        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:local="clr-namespace:WpfApp3"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:Custom="http://infragistics.com/DockManager" x:Class="WpfApp3.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow X" Height="350" Width="525">
    <Grid>
        <TextBox local:EventHelper.IsEventRaising="True"
                 local:EventHelper.InputChanged="InputChangedHandler"
                             />
    </Grid>
</Window>

0 件のコメント:

コメントを投稿