【问题标题】:How to make MouseOver event in MVVM?如何在 MVVM 中制作 MouseOver 事件?
【发布时间】:2016-03-25 13:43:34
【问题描述】:

我使用以下代码导航按钮点击:

XAML:

<Button x:Name ="Btn_Import" Grid.Row="33" Grid.Column="15" Grid.ColumnSpan="36" Grid.RowSpan="36" Command="{Binding NavigateCommand}"  CommandParameter="ViewImportProgress"/>

视图模型:

public DelegateCommand<string> NavigateCommand { get; set; }

public MainButtonsViewModel(IRegionManager regionManager, IMainMenuTooltipViewer mainMenuTooltipViewer)
        {
            NavigateCommand = new DelegateCommand<string>(Navigate); 
        }

 private void Navigate(string uri)
        {
            regionManager.RequestNavigate("ScreenNavigationRegion", uri); 


        }

而且效果很好。现在我的问题是,在 MVVM 模式中并使用 Prism 时,在 MouseOver 事件而不是 MouseClick 事件上进行导航的等效代码是什么?

【问题讨论】:

    标签: wpf mvvm prism


    【解决方案1】:

    你可以使用交互

    声明命名空间

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    

    你可以将命令绑定到事件

    <Button Content="Navigate" >
    
        <i:Interaction.Triggers>
    
            <i:EventTrigger EventName="MouseEnter">
    
                <i:InvokeCommandAction Command="{Binding NavigateCommand}"   CommandParameter="ViewImportProgress"/>
    
            </i:EventTrigger>
    
        </i:Interaction.Triggers>
    
    </Button>
    

    【讨论】:

    • 它只是示例如何将命令绑定到事件。您可以使用任何其他命令代替 NavigationCommand。 NavigationCommand 的实现依赖于项目基础设施。例如,您可以使用方法“void Navigate(Type vm)”定义 NavigationService,将其注册到 DI 容器中,而不仅仅是在命令 navigationService.Navigate(typeof(yourNewVM)); 中使用
    【解决方案2】:

    我个人更喜欢使用EventToCommand,因为PassEventArgsToCommand 属性:

    xmlns:cmd ="http://www.galasoft.ch/mvvmlight"
    
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding KeyDownCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    

    然后你像这样使用它:

    public ICommand KeyDownCommand { get { return new RelayCommand<KeyEventArgs>(OnKeyDown); } }
    private void OnKeyDown(KeyEventArgs args)
    {
        if (args.Key == Key.Insert)
            InsertSomething();
    }
    

    实际上,鼠标消息并不那么重要,因为我通常用代理代替参数,除了其他东西之外,它还允许我的视图模型引发捕获/释放事件等。虽然对于击键之类的事情来说它很方便或需要获取参数并使用代理的关闭事件等只是添加了另一个不必要的抽象层。

    【讨论】:

    • 本例中的cmd命名空间是什么?
    【解决方案3】:

    首先,您要为控件设置样式,比如一个按钮,如问题中所示:

        <Style x:Key="MyButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="{StaticResource SomeBrush}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Template" Value="{DynamicResource MyButtonTemplate}"/>
    </Style>
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type ButtonBase}">
        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
            <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="Button.IsDefaulted" Value="True">
                <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" TargetName="border" Value="{Binding IsMouseOverMenuButton, Converter={StaticResource BoolToBrushConverter}}"/>
                <Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    接下来,在你的虚拟机中设置属性:

    public bool IsMouseOverMenuButton
        {
            get => _isMouseOverMenuButton;
            set
            {
                if (_isMouseOverMenuButton != value)
                {
                    _isMouseOverMenuButton = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsMouseOverMenuButton"));
                }
            }
        }
    

    别忘了转换器。

    顺便说一句,如果你想要一个简单的技巧,当你在 XAML 文件上的控件上时,右键单击它,然后在菜单中转到“编辑样式”。然后我去“编辑副本”,它给了我我需要的一切。您可以直接在资源字典中编辑样式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 2021-10-29
      • 1970-01-01
      • 2013-01-26
      • 2011-11-16
      • 1970-01-01
      相关资源
      最近更新 更多