안녕하세요, WPF 초보입니다.
검색에 검색을 하다 여기까지 흘러 들어왔습니다. 물론 다른 내용으로 검색하다 흘러 들어 왔지만, 내용이 알차여 몇일을 정작하였습니다.
웹 BE가 베이스라 wpf 가 마냥 쉽지많은 않네요
desktop 앱으로 라인 이미지를 가로로 쌓아야 하는 경우가 있는데, 이때 확대시 위아래 좌우 스크롤이 되어야 하는 상황입니다.
위아래 스크롤은 xaml 에서 ScrollVeiwer 로 간단하게 구현이 되는데, 가로 스크롤이 구현이 안되더라구요
(일반적으로 shift + 휠 조작으로 가능하던데, 이것도 구현해야 할 줄은 생각못했습니다)
그래서 하루종일 서치하여 결국 해결 하기는 했는데 이게 맞는 방법 인지 모르겠습니다.
MVVM 패턴을 이용 하고 있고, 코드 비하인드에서 직접 UI를 조작 하는 방식으로 구현이 되어버려서 MVVM 패턴에 위배되는거 같은데 다른 옵션을 찾아보아도 도통 보이질 않네요
**CommunityToolkit.MVVM 라이브러리 사용중에 있습니다.
다른 옵션이 있으면 알려주실수 있을까 하여 질문 남깁니다.
public partial class CustomerPage : Page
{
public CustomerPage()
{
InitializeComponent();
DataContext = App.Current.Services.GetService(typeof(CustomerViewModel));
WeakReferenceMessenger.Default.Register<HorizontalScrollMessage>(this, (r, m) =>
{
if (m.ScrollLeft)
{
scrollViewer.LineLeft();
}
else
{
scrollViewer.LineRight();
}
});
}
}
이렇게 코드 비하인드에서 직접 UI를 조작 하고, ViewModel 에서는 메세징으로 전달하는 방법입니다.
// 가로 스크롤처리
private void OnPreviewMouseWheel(MouseWheelEventArgs e)
{
ArgumentNullException.ThrowIfNull(e);
// 지금 키보드가 눌러 져있는지 확인
if (Keyboard.Modifiers == ModifierKeys.Shift)
{
switch (e.Delta)
{
// 아래로 굴리면 델타는 줄어들고
// 위로 굴리면 델타는 늘어난다
// Scroll left
case > 0:
WeakReferenceMessenger.Default.Send(new HorizontalScrollMessage { ScrollLeft = true });
break;
// Scroll right
case < 0:
WeakReferenceMessenger.Default.Send(new HorizontalScrollMessage { ScrollLeft = false });
break;
}
// 잡히면 아무 동작도 하지 않는다.
e.Handled = true;
}
}
위에 보시는 코드는 , ViewModel 에서 Command 처리를 하는 부분이구요
<ScrollViewer x:Name="scrollViewer"
Grid.Row="2"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<b:Interaction.Triggers>
<b:EventTrigger EventName="PreviewMouseWheel">
<common:EventToCommand Command="{Binding PreviewMouseWheelCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
위에 보시는 코드는 xaml 코드입니다.
CommunityToolkit.MVVM 에서는 이벤트를 커멘드와 같이 보내는게 어려워, copilot 의 도움을 받아 EventToCommand 를 정의 하였습니다.
namespace HSIClient.Common;
using System.Windows;
using System.Windows.Input;
using Microsoft.Xaml.Behaviors;
public class EventToCommand : TriggerAction<DependencyObject>
{
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(EventToCommand), new PropertyMetadata(null));
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter", typeof(object), typeof(EventToCommand), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
protected override void Invoke(object parameter)
{
Command?.Execute(CommandParameter ?? parameter);
}
}
위의 코드는 EventToCommand 입니다
코드 비하인드에서 직접 조작하는 방법이 아닌 다른 방법이 있을까요 ?
고민을 같이 읽어주셔서 감사합니다.