这可能对MVVM模式有些过分,但对我来说这是新的,我很想知道它是否可行。
如果我附加到Window的MouseMove事件并执行DragMove,我可以移动无边框窗口。我可以通过MVVM中的其他方法实现这一点,还是应该接受将此代码添加到Window的代码隐藏中?
答案 0 :(得分:3)
我个人认为使用MVVM的任何解决方案都不会使这个代码更好。此外,这通常与视图相关,并且与您正在显示的数据无关。
答案 1 :(得分:3)
这是纯UI逻辑,不属于ViewModel。你不想把它放在你的代码隐藏中的唯一原因是重复使用,这可以通过自定义的Window派生控件更好地解决。
答案 2 :(得分:2)
恕我直言,除非这是影响你的数据(又称模型)的东西,否则它是View代码,应该在View的代码隐藏中,而不是在模型中。
答案 3 :(得分:2)
我要回答你的问题。答案是肯定的。我正在使用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>
在ViewModel中:
[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的任何事件都包含View作为发件人。所以,在这里,我们只需在ViewModel中的事件处理程序中调用视图上的方法。
我正在开发的项目不使用代码隐藏(即使在MVVM中不推荐使用它)。
答案 4 :(得分: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;
}
和viewModel中的类似内容
#region Public Event Handlers
public event EventHandler<EventArgs> RequestClose;
public event EventHandler<EventArgs> RequestMinimize;
#endregion
使用ICommand界面...
#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());
}
希望这有帮助!
答案 5 :(得分:0)
我知道这是一个老问题。但是,我准备了另一个简单的实现。使用以下行为使窗口可移动:
public class WindowMoveBehavior : Behavior<Grid>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
}
protected override void OnDetaching()
{
AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
base.OnDetaching();
}
private void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Window.GetWindow(AssociatedObject).DragMove();
}
}
Xaml示例:
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<i:Interaction.Behaviors>
<behaviors:WindowMoveBehavior/>
</i:Interaction.Behaviors>
<!-- different controls and content -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>