将IsMouseOver绑定到UserControl中的ViewModel

时间:2018-05-19 19:32:06

标签: c# wpf mvvm viewmodel

我正在创建一个自定义菜单控件,可以在使用MVVM选择或悬停时更改图像(.PNG文件)。现在,当我选择一个菜单项时,图像会发生变化,但我正在努力让悬停部分工作。以下是我将ViewModel分配给View的代码:

<DataTemplate DataType="{x:Type viewModel:MyMenuItem}">
    <view:MyMenuItemControl/>
</DataTemplate>

以下是我的UserControl代码:

<Grid>
    <Image Source="{Binding DisplayImage}">
        <Image.InputBindings>
            <MouseBinding Gesture="LeftClick" Command="{Binding LeftClickCommand}"/>
        </Image.InputBindings>
        <Image.Style>
            <Style TargetType="{x:Type Image}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="IsMouseOver" Value="{Binding Path=IsHovered, Mode=OneWayToSource}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</Grid>

由于IsMouseOver属性是只读的,因此无法编译,但我无法弄清楚在发生此触发器时如何更新ViewModel。我是WPF和MVVM的新手,所以如果这有点无知,我会道歉。我搜索了大约2个小时,但未能找到我能理解的答案并继续前进。

编辑:这是一个似乎不起作用的选项2。当我将鼠标悬停在项目上时,这会编译但不会更新图像:

<Grid>
    <Image Source="{Binding DisplayImage}">
        <Image.InputBindings>
            <MouseBinding Gesture="LeftClick"  Command="{Binding LeftClickCommand}"/>
        </Image.InputBindings>
        <Image.Style>
            <Style TargetType="{x:Type Image}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Source" Value="{Binding DisplayHoverImage}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</Grid>

解决方案我要去:

<Grid>
    <Image>
        <Image.InputBindings>
            <MouseBinding Gesture="LeftClick"  Command="{Binding LeftClickCommand}"/>
        </Image.InputBindings>
        <Image.Style>
            <Style TargetType="{x:Type Image}">
                <Setter Property="Source" Value="{Binding DisplayImage}"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Source" Value="{Binding DisplayHoverImage}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</Grid>

1 个答案:

答案 0 :(得分:-1)

首先,定义一个新控件,该控件派生自您要使用的控件:

public class HoverOverImage : Image
{
    public static DependencyProperty MouseOverFrameAreaProperty = DependencyProperty.Register("MouseOverFrameArea", typeof(bool), typeof(HoverOverImage)
        , new FrameworkPropertyMetadata(false, OnMouseOverFrameAreaChanged));
    private bool _mouseOverFrameArea = false;

    public bool MouseOverFrameArea
    {
        get => _mouseOverFrameArea;
        set
        {
            _mouseOverFrameArea = value;
            if (DataContext != null && DataContext.GetType()==typeof(MyViewModel))
                ((MyViewModel)DataContext).MouseOverFrameArea = value;
        }
    }
    private static void OnMouseOverFrameAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((HoverOverImage)d).MouseOverFrameArea = (bool)e.NewValue;
    }
}

然后在XAML中,您应该添加:

<local:HoverOverImage x:Name="framesourceImage" RenderOptions.BitmapScalingMode="NearestNeighbor" Source="{Binding CurrentFrame}">
                    <local:HoverOverImage.Style>
                        <Style TargetType="{x:Type local:HoverOverImage}">
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="MouseOverFrameArea" Value="True"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="False">
                                    <Setter Property="MouseOverFrameArea" Value="False"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </local:HoverOverImage.Style>