2010-08-06 3 views
3

이것은 MVVM 패턴에서 과도한 것일 수 있지만 새로운 것이므로 가능한지 알고 싶습니다.MVVM을 사용하여 WPF 창을 어떻게 이동해야합니까?

Window의 MouseMove 이벤트에 연결하고 DragMove를 수행하면 테두리가없는 윈도우를 이동할 수 있습니다. MVVM의 다른 방법으로이 작업을 수행 할 수 있습니까? 아니면이 코드를 Window의 코드 숨김에 추가 할 수 있습니까?

답변

3

이것은 순수 UI 로직이며 ViewModel에 속하지 않습니다. 이 코드를 코드 숨김에 넣고 싶지 않은 유일한 이유는 다시 사용하기위한 것이며 사용자 정의 Window 파생 컨트롤을 사용하면 더 효율적으로 해결할 수 있습니다.

2

IMHO, 이는 데이터 (일명 모델)에 영향을주는 것이 아닌 경우보기 코드이며보기의 코드 숨김이 아니라 모델에 있어야합니다.

3

개인적으로 MVVM을 사용하는 모든 솔루션이이 코드를 더 좋게 만들지 않을 것이라고 생각합니다. 또한 일반적으로보기와 관련이 있으며 표시된 데이터와 관련이 없습니다.

+0

이 사람에게 절대적으로 동의합니다! – ktutnik

1

나는 귀하의 질문에 실제로 대답 할 것입니다. 대답은 '예'입니다. Cinch을 사용하여 이벤트 바인딩 및보기 모델 생성을 도와줍니다. 이 솔루션은 DragMove를 사용하지만 코드 숨김의 일부로는 사용하지 않습니다 (이것이 내가 묻는 것입니다).

이벤트는 XAML에서 바인딩 :

<Window 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:cinchV2="clr-namespace:Cinch;assembly=Cinch.WPF" 
    ...> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseLeftButtonDown"> 
      <cinchV2:EventToCommandTrigger Command="{Binding MouseLeftButtonDown}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <Grid> 
     ... 
    </Grid> 
</Window> 

을 뷰 모델에서 :

[ExportViewModel("MainViewModel")] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
internal sealed class MainViewModel : ViewModelBase 
{ 
    public SimpleCommand<object, EventToCommandArgs> MouseLeftButtonDown { get; private set; } 

    [ImportingConstructor] 
    public MainViewModel(IUIVisualizerService uiVisualizerService) 
    { 
     ... 
     MouseLeftButtonDown = new SimpleCommand<object, EventToCommandArgs>(OnMouseLeftButtonDown); 
    } 

    private static void OnMouseLeftButtonDown(EventToCommandArgs e) 
    { 
     ((Window)e.Sender).DragMove(); 
    } 
} 

상당히 간단 하죠? UI에서 가져온 이벤트에는 보낸 사람으로보기가 포함됩니다. 여기서는 단순히 ViewModel의 이벤트 핸들러 내에서 뷰에 대한 메소드를 호출합니다.

저는 MVVM에서 권장되지 않는 코드 숨김을 사용하고 있습니다.

2

나는 질문에 조금 늦었다 고 알고있다. 그러나 이것은 내가 언젠가 지금 사용하고있는 것이며, 그것은 매력처럼 작동한다.

DashboardViewModel viewModel; 
public DashboardView() 
{ 
    InitializeComponent(); 
    viewModel = new DashboardViewModel(); 
    viewModel.RequestClose += (s, e) => Application.Current.Dispatcher.Invoke(this.Close); 
    viewModel.RequestMinimize += (s, e) => Application.Current.Dispatcher.Invoke(() => { this.WindowState = WindowState.Minimized; }); 
    DataContext = viewModel; 
} 

와 뷰 모델 ICommand의 인터페이스를 사용하여

#region Public Event Handlers 
public event EventHandler<EventArgs> RequestClose; 
public event EventHandler<EventArgs> RequestMinimize; 
#endregion 

에서이 같은 ...

#region ICommand Members 
public ICommand CloseCommand { get; private set; } 
public ICommand MinimizeCommand { get; private set; } 
#endregion 

구성 명령 ... 여기

private void SetupCommands() 
{ 
    CloseCommand = new RelayCommand(CloseApplication); 
    MinimizeCommand = new RelayCommand(MinimizeApplication); 
} 

입니다 RelayCommand 클래스 그리고 몇 가지 예제 방법

public class RelayCommand : ICommand 
{ 
#region Private Readonly Properties 
private readonly Action<object> executeCommand; 
private readonly Predicate<object> canExecute; 
#endregion 

#region Constructors 
public RelayCommand(Action<object> execute) : this(execute, null) 
{ 

} 
public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
{ 
    if (execute == null) 
     throw new ArgumentNullException("execute"); 
    this.executeCommand = execute; 
    this.canExecute = canExecute; 
} 
#endregion 

#region Public ICommand Members 
public bool CanExecute(object parameter) 
{ 
    return canExecute == null ? true : canExecute(parameter); 
} 
public event EventHandler CanExecuteChanged 
{ 
    add { CommandManager.RequerySuggested += value; } 
    remove { CommandManager.RequerySuggested -= value; } 
} 
public void Execute(object parameter) 
{ 
    executeCommand(parameter); 
} 
#endregion 
} 

...이 도움이

private void MinimizeApplication(object obj) 
{ 
    RequestMinimize(this, new EventArgs()); 
} 
private void CloseApplication(object obj) 
{ 
    RequestClose(this, new EventArgs()); 
} 

희망!

관련 문제