我启动了MVVM项目,并在ViewModel上设置了TextBlock上的View绑定所有事件。我设置了3个命令(MouseEnter,MouseLeave和MouseDown)。但只有MouseEnter和MouseDown被触发,MouseLeave事件没有触发
这是视图
<Window x:Class="SilentUpdate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:local="clr-namespace:SilentUpdate"
xmlns:res="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Background="Gainsboro"
WindowStartupLocation="CenterScreen" WindowStyle="None"
Title="" Height="600" Width="1024">
<Grid>
<Grid.Resources>
<ResourceDictionary>
<Style TargetType="TextBlock" x:Key="IconText">
<Setter Property="FontSize" Value="32"/>
<Setter Property="Foreground" Value="#ADADAD"/>
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Segoe UI Symbol"/>
<Setter Property="Margin" Value="10,10,10,10"/>
</Style>
<res:String x:Key="homeIcon"></res:String>
<res:String x:Key="settingsIcon"></res:String>
<res:String x:Key="previewIcon"></res:String>
<res:String x:Key="runIcon"></res:String>
<res:String x:Key="saveIcon"></res:String>
<res:String x:Key="exitIcon"></res:String>
<res:String x:Key="warningIcon"></res:String>
<res:String x:Key="folderIcon"></res:String>
</ResourceDictionary>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel x:Name="Navibar" Orientation="Vertical" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Background="#0096C1">
<TextBlock Name="home"
Foreground="{Binding HomeColor}"
Text="{StaticResource homeIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=home}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=home}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding HomeCommand}"
CommandParameter="{Binding ElementName=home}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Name="settings"
Text="{StaticResource settingsIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=settings}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=settings}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding SettingCommand}"
CommandParameter="{Binding ElementName=settings}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Name="preview"
IsEnabled="{Binding PreviewStatus, Mode=OneWay}"
Text="{StaticResource previewIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=preview}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=preview}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding PreviewCommand}"
CommandParameter="{Binding ElementName=preview}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Name="run"
IsEnabled="{Binding RunStatus, Mode=OneWay}"
Text="{StaticResource runIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=run}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=run}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding RunCommand}"
CommandParameter="{Binding ElementName=run}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Name="save"
IsEnabled="{Binding SaveStatus, Mode=OneWay}"
Text="{StaticResource saveIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=save}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=save}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding SaveCommand}"
CommandParameter="{Binding ElementName=save}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Name="exit"
Text="{StaticResource exitIcon}"
Style="{StaticResource IconText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding EventMouseOver}"
CommandParameter="{Binding ElementName=exit}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction Command="{Binding MouseLeaveButton}"
CommandParameter="{Binding ElementName=exit}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding ExitButtonCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</StackPanel>
</Grid>
</Window>
这是ViewModel
using SilentUpdate.Helpers;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace SilentUpdate.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
#region Property change interface implement
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseProperChanged (string prop)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
#endregion
#region Button Status
// To keep track the active click button
private TextBlock activeButton;
private Brush homeColor;
private bool previewStatus, runStatus, saveStatus;
public Brush HomeColor
{
get { return this.homeColor; }
set { this.homeColor = value; RaiseProperChanged("HomeColor"); }
}
public bool PreviewStatus
{
get { return this.previewStatus; }
set
{
this.previewStatus = value;
RaiseProperChanged("PreviewStatus");
}
}
public bool RunStatus
{
get { return this.runStatus; }
set
{
this.runStatus = value;
RaiseProperChanged("RunStatus");
}
}
public bool SaveStatus
{
get { return this.saveStatus; }
set
{
this.saveStatus = value;
RaiseProperChanged("SaveStatus");
}
}
#endregion
#region Event Binding
// Command for binding to the event
private ICommand exitButtonCommand, eventMouseOver, eventMouseLeave;
private ICommand homeCommand, settingCommand, previewCommand, runCommand, saveCommand;
private bool canExecute = true;
public bool CanExecute
{
get { return this.canExecute; }
set
{
if (this.canExecute == value)
{
return;
}
this.canExecute = value;
}
}
/// <summary>
/// Public for binding to Exit button
/// </summary>
public ICommand ExitButtonCommand
{
get { return this.exitButtonCommand; }
set
{
this.exitButtonCommand = value;
}
}
/// <summary>
/// Exit the application when Exit button click binding to ExitButtonCommand
/// </summary>
/// <param name="obj"></param>
public void ExitApp(object obj)
{
Application.Current.Shutdown();
}
/// <summary>
/// Public for binding to Home button
/// </summary>
public ICommand HomeCommand
{
get { return this.homeCommand; }
set
{
this.homeCommand = value;
}
}
/// <summary>
/// Actual home event, will display the home page
/// This will update the page binding variable
/// </summary>
/// <param name="obj"></param>
public void HomeEvent (object obj)
{
// Change the active button
ChangeActive((TextBlock)obj);
// Change the button status
PreviewStatus = false;
RunStatus = false;
SaveStatus = false;
HomeColor = new SolidColorBrush(Colors.White);
MessageBox.Show("HomeEvent");
}
/// <summary>
/// Public for binding to Setting button
/// </summary>
public ICommand SettingCommand
{
get { return this.settingCommand; }
set
{
this.settingCommand = value;
}
}
/// <summary>
/// Actual Setting event, will display the setting page
/// This will update the page binding variable
/// </summary>
/// <param name="obj"></param>
public void SettingEvent(object obj)
{
// Change the active button
ChangeActive((TextBlock)obj);
// Change the button status
PreviewStatus = true;
RunStatus = false;
SaveStatus = false;
MessageBox.Show("SettingEvent");
}
/// <summary>
/// Public for binding to Preview button
/// </summary>
public ICommand PreviewCommand
{
get { return this.previewCommand; }
set
{
this.previewCommand = value;
}
}
/// <summary>
/// Actual Preview event, will display the preview page
/// based on the Messenger sending to the page for the environment
/// setting by the setting page
/// This will update the page binding variable
/// </summary>
/// <param name="obj"></param>
public void PreviewEvent(object obj)
{
// Change the active button
ChangeActive((TextBlock)obj);
// Change the button status
PreviewStatus = true;
RunStatus = true;
SaveStatus = false;
MessageBox.Show("PreviewEvent");
}
/// <summary>
/// Public for binding to Run button
/// </summary>
public ICommand RunCommand
{
get { return this.runCommand; }
set
{
this.runCommand = value;
}
}
/// <summary>
/// Actual Preview event, will display the after run page
/// based on the Messenger sending to the page for the environment
/// setting by the setting page and the selection of the list file
/// from the Preview page
/// This will update the page binding variable
/// </summary>
/// <param name="obj"></param>
public void RunEvent(object obj)
{
// Change the active button
ChangeActive((TextBlock)obj);
// Change the button status
PreviewStatus = true;
RunStatus = true;
SaveStatus = true;
MessageBox.Show("RunEvent");
}
/// <summary>
/// Public for binding to Save button
/// </summary>
public ICommand SaveCommand
{
get { return this.saveCommand; }
set
{
this.saveCommand = value;
}
}
/// <summary>
/// Actual Save event, will generate the PDF file log
/// And launch the PDF file based on default application setting
/// </summary>
/// <param name="obj"></param>
public void SaveEvent(object obj)
{
ChangeActive((TextBlock)obj);
MessageBox.Show("SaveEvent");
}
/// <summary>
/// This event uses by all button to change color to active state
/// </summary>
public ICommand EventMouseOver
{
get { return this.eventMouseOver; }
set
{
this.eventMouseOver = value;
}
}
/// <summary>
/// Actual mouse enter event for binding command EventMouseOver
/// </summary>
/// <param name="obj">The target object of button</param>
public void MouseOverButton(object obj)
{
// Casting the object
TextBlock target = (TextBlock)obj;
if (activeButton == null)
{
// High light target
activeButton = target;
}
// High light target
HighLightText(target, true);
}
/// <summary>
/// This event uses by all button to change color to inactive state
/// </summary>
public ICommand EventMouseLeave
{
get { return this.eventMouseLeave; }
set { this.eventMouseLeave = value; }
}
/// <summary>
/// Actual mouse leave event for binding command EventMouseLeave
/// </summary>
/// <param name="obj">The target object of button</param>
private void MouseLeaveButton(object obj)
{
// Casting the object
TextBlock target = (TextBlock)obj;
if (target.Equals(activeButton) == false)
{
HighLightText(target, false);
}
HighLightText(activeButton, true);
}
/// <summary>
/// Update the canExecute property
/// </summary>
/// <param name="obj"></param>
public void ChangeCanExecute(object obj)
{
canExecute = !canExecute;
}
#endregion
#region Constructor
public MainViewModel()
{
exitButtonCommand = new RelayCommand(ExitApp, Param => this.canExecute);
eventMouseOver = new RelayCommand(MouseOverButton);
eventMouseLeave = new RelayCommand(MouseLeaveButton);
homeCommand = new RelayCommand(HomeEvent);
settingCommand = new RelayCommand(SettingEvent);
previewCommand = new RelayCommand(PreviewEvent);
runCommand = new RelayCommand(RunEvent);
saveCommand = new RelayCommand(SaveEvent);
// Set the Preview status disable when start
PreviewStatus = false;
// Set the Run status disable when start
RunStatus = false;
// Set the Save status disable when start
SaveStatus = false;
// HomeColor
HomeColor = new SolidColorBrush(Colors.White);
}
#endregion
#region Private Helper
private void HighLightText(TextBlock target, bool isHighlight)
{
if (isHighlight)
{
target.Foreground = new SolidColorBrush(Colors.White);
}
else
{
target.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(68, 173, 173, 173));
}
}
private void ChangeActive (TextBlock target)
{
if (activeButton != null)
{
HighLightText(activeButton, false);
}
activeButton = target;
HighLightText(activeButton, true);
activeButton.ReleaseMouseCapture();
target.ReleaseMouseCapture();
HomeColor = new SolidColorBrush(System.Windows.Media.Color.FromArgb(68, 173, 173, 173));
}
#endregion
}
}
答案 0 :(得分:0)
我对实现的错误,我应该将UI逻辑保留在view而不是viewmodel中。这解决了问题