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

728x90
반응형
728x170

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
    }
}

 

728x90

 

▶ 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>
728x90
반응형
그리드형(광고전용)
Posted by 사용자 icodebroker

댓글을 달아 주세요