첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ ScrollViewer 클래스 : 시프트 키와 마우스 휠을 사용해 가로 스크롤 처리하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


ScrollViewerHelper.cs

 

 

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Media;

 

namespace TestProject

{

    /// <summary>

    /// 스크롤 뷰어 헬퍼

    /// </summary>

    public static class ScrollViewerHelper

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Static

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

 

        #region Field

 

        /// <summary>

        /// 시프트/휠 사용 여부 속성

        /// </summary>

        public static readonly DependencyProperty UseShiftWheelProperty = DependencyProperty.RegisterAttached

        (

            "UseShiftWheel",

            typeof(bool),

            typeof(ScrollViewerHelper),

            new PropertyMetadata(false, UseShiftWheelPropertyChangedCallback)

        );

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 시프트/휠 사용 여부 설정하기 - SetUseShiftWheel(uiElement, value)

 

        /// <summary>

        /// 시프트/휠 사용 여부 설정하기

        /// </summary>

        /// <param name="uiElement">UI 엘리먼트</param>

        /// <param name="value"></param>

        public static void SetUseShiftWheel(UIElement uiElement, bool value) => uiElement.SetValue(UseShiftWheelProperty, value);

 

        #endregion

        #region 시프트/휠 사용 여부 구하기 - GetUseShiftWheel(uiElement)

 

        /// <summary>

        /// 시프트/휠 사용 여부 구하기

        /// </summary>

        /// <param name="uiElement">UI 엘리먼트</param>

        /// <returns>시프트/휠 사용 여부</returns>

        public static bool GetUseShiftWheel(UIElement uiElement) => (bool)uiElement.GetValue(UseShiftWheelProperty);

 

        #endregion

 

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

        ////////////////////////////////////////////////////////////////////// Event

 

        #region UI 엘리먼트 마우스 휠 PREVIEW 처리하기 - uiElement_PreviewMouseWheel(sender, e)

 

        /// <summary>

        /// UI 엘리먼트 마우스 휠 PREVIEW 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private static void uiElement_PreviewMouseWheel(object sender, MouseWheelEventArgs e)

        {

            ScrollViewer scrollViewer = ((UIElement)sender).FindDescendant<ScrollViewer>();

 

            if(scrollViewer == null)

            {

                return;

            }

 

            if(Keyboard.Modifiers != ModifierKeys.Shift)

            {

                return;

            }

 

            if(e.Delta < 0)

            {

                scrollViewer.LineRight();

            }

            else

            {

                scrollViewer.LineLeft();

            }

 

            e.Handled = true;

        }

 

        #endregion

 

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

 

        #region 시프트/휠 사용 여부 속성 변경시 콜백 처리하기 - UseShiftWheelPropertyChangedCallback(dependencyObject, e)

 

        /// <summary>

        /// 시프트/휠 사용 여부 속성 변경시 콜백 처리하기

        /// </summary>

        /// <param name="dependencyObject">의존 객체</param>

        /// <param name="e">이벤트 인자</param>

        private static void UseShiftWheelPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)

        {

            UIElement uiElement = dependencyObject as UIElement;

 

            if(uiElement == null)

            {

                throw new Exception("Attached property must be used with UIElement.");

            }

 

            if((bool)e.NewValue)

            {

                uiElement.PreviewMouseWheel += uiElement_PreviewMouseWheel;

            }

            else

            {

                uiElement.PreviewMouseWheel -= uiElement_PreviewMouseWheel;

            }

        }

 

        #endregion

        #region 자손 찾기 - FindDescendant<T>(dependencyObject)

 

        /// <summary>

        /// 자손 찾기

        /// </summary>

        /// <typeparam name="T">자손 타입</typeparam>

        /// <param name="dependencyObject">의존 객체</param>

        /// <returns>자손</returns>

        private static T FindDescendant<T>(this DependencyObject dependencyObject) where T : DependencyObject

        {

            if(dependencyObject == null)

            {

                return null;

            }

 

            int count = VisualTreeHelper.GetChildrenCount(dependencyObject);

 

            for(var i = 0; i < count; i++)

            {

                DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);

 

                T result = child as T ?? FindDescendant<T>(child);

 

                if(result != null)

                {

                    return result;

                }

            }

 

            return null;

        }

 

        #endregion

    }

}

 

 

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:src="clr-namespace:TestProject"

    Width="800"

    Height="600"

    Title="ScrollViewer 클래스 : 시프트 키와 마우스 휠을 사용해 가로 스크롤 처리하기"

    FontFamily="나눔고딕코딩"

    FontSize="16">

    <Grid src:ScrollViewerHelper.UseShiftWheel="True">

        <ScrollViewer

            HorizontalScrollBarVisibility="Auto"

            VerticalScrollBarVisibility="Auto">

            <StackPanel Orientation="Horizontal">

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

                <Rectangle Width="50" Height="50" Margin="10" Fill="Blue" />

            </StackPanel>

        </ScrollViewer>

    </Grid>

</Window>

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요