如何在MVVM WPF(c#)中写入这些特定行?

时间:2019-02-04 03:14:13

标签: c# mvvm mouseenter

   Console.WriteLine(DateTime.Now.ToLongTimeString());
            string name = (sender as Button).Name;

我必须将这两行转换为 MVVM 。以下是我的代码。

ViewModel.cs

       public ICommand MouseEnterCommand
                {
                    get
                    {
                        return new RelayCommand(a => this.Executemethod(), p => Canexecutemethod());
                    }
                }
                public bool Canexecutemethod()
                {
                    return true;
                }

                public void Executemethod(){
            Console.WriteLine(DateTime.Now.ToLongTimeString());
            string name = (sender as Button).Name;
switch(name)
            {
case "btn1":
...
case "btn2":
            ...
          }}

其中 btn1 btn2 是按钮名称.....我总共有四个按钮

View.xaml:

   <UserControl
    xmlns:interact="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    ..>
    <Grid>
    <Button Name="btn1">
    <interact:Interaction.Triggers>
    <interact:EventTrigger EventName="MouseEnter">
    <interact:InvokeCommandAction Command="{Binding  Path=DataContext.ZoomInCommand}" CommandParameter="{Binding }" />
    </interact:EventTrigger>
    </interact:Interaction.Triggers>
    </Button>
    </Grid>
    </UserControl>

请帮助我在MVVM中编写这些行。。谢谢

2 个答案:

答案 0 :(得分:0)

我认为,这个适合您

ViewModel.cs

 public class ViewModel
{
    public ICommand MouseEnterCommand
    {
        get
        {
            return new RelayCommand(a => this.Executemethod(a), p => Canexecutemethod(p));
        }
    }

    public bool Canexecutemethod(object a)
    {
        return true;
    }

    public void Executemethod(object p)
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString());

        string name = Convert.ToString(p);

        switch (name)
        {
            default:
                break;
        }

    }
}

View.xaml ::

<UserControl
    xmlns:interact="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    ..>
    <Grid>

            <Button Height="25" Width="150">
                <interact:Interaction.Triggers>
                    <interact:EventTrigger EventName="MouseEnter">
                    <interact:InvokeCommandAction Command="{Binding  MouseEnterCommand}" CommandParameter="MouseEnter" />
                    </interact:EventTrigger>
                </interact:Interaction.Triggers>
            </Button>

    </Grid>
</UserControl>

答案 1 :(得分:0)

在这里,您将需要EventToCommandBehavior,它将Click事件的事件参数传递给viewModel。像这样:

/// <summary>
/// Behavior that will connect an UI event to a viewmodel Command,
/// allowing the event arguments to be passed as the CommandParameter.
/// </summary>
public class EventToCommandBehavior : Behavior<FrameworkElement>
{
    // Event
    public string Event
    {
        get { return ( string ) GetValue( EventProperty ); }
        set { SetValue( EventProperty, value ); }
    }

    public static readonly DependencyProperty EventProperty =
        DependencyProperty.Register( nameof( Event ), typeof( string ), typeof( EventToCommandBehavior ),
            new PropertyMetadata( null, OnEventChanged ) );

    // Command
    public ICommand Command
    {
        get { return ( ICommand ) GetValue( CommandProperty ); }
        set { SetValue( CommandProperty, value ); }
    }

    public static readonly DependencyProperty CommandProperty
        = DependencyProperty.Register( nameof( Command ), typeof( ICommand ), typeof( EventToCommandBehavior ), new PropertyMetadata( null ) );

    // PassArguments (default: false)
    public bool PassArguments
    {
        get { return ( bool ) GetValue( PassArgumentsProperty ); }
        set { SetValue( PassArgumentsProperty, value ); }
    }

    public static readonly DependencyProperty PassArgumentsProperty
        = DependencyProperty.Register( nameof( PassArguments ), typeof( bool ), typeof( EventToCommandBehavior ), new PropertyMetadata( false ) );

    protected override void OnAttached()
    {
        AttachHandler( Event ); // initial set
    }

    /// <summary>
    /// Attaches the handler to the event
    /// </summary>
    private void AttachHandler( string eventName )
    {
        // detach old event
        if ( oldEvent != null )
            oldEvent.RemoveEventHandler( AssociatedObject, handler );

        // attach new event
        if ( !string.IsNullOrEmpty( eventName ) )
        {
            EventInfo ei = AssociatedObject.GetType().GetEvent( eventName );
            if ( ei != null )
            {
                MethodInfo mi = GetType().GetMethod( nameof( ExecuteCommand ), BindingFlags.Instance | BindingFlags.NonPublic );
                if ( mi != null )
                {
                    handler = Delegate.CreateDelegate( ei.EventHandlerType, this, mi );
                    ei.AddEventHandler( AssociatedObject, handler );
                    oldEvent = ei; // store to detach in case the Event property changes
                }
                else
                {
                    throw new InvalidOperationException(
                        $"Method {nameof( ExecuteCommand )} not found in class {nameof( EventToCommandBehavior )}" );
                }
            }
            else
            {
                throw new ArgumentException( $"The event '{eventName}' was not found on type '{AssociatedObject.GetType().Name}'" );
            }
        }
    }

    private static void OnEventChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        var beh = ( EventToCommandBehavior ) d;

        if ( beh.AssociatedObject != null ) // is not yet attached at initial load
            beh.AttachHandler( ( string ) e.NewValue );
    }

    /// <summary>
    /// Executes the Command
    /// </summary>
    // ReSharper disable once UnusedParameter.Local
    private void ExecuteCommand( object sender, EventArgs e )
    {
        object parameter = PassArguments ? e : null;

        if ( Command != null )
        {
            if ( Command.CanExecute( parameter ) )
                Command.Execute( parameter );
        }
    }

    private Delegate handler;
    private EventInfo oldEvent;
}

在您的xaml中使用此行为使按钮将RoutedEventArgs args传递给命令,如下所示:

<UserControl x:Class="YourNameSpace.YourClass">
xmlns:beh="clr-namespace:YourNameSpace.Behaviors"
...
<StackPanel Orientation="Horizontal" >
    <Button Margin="2" Content="Button 1" Name="btnButton1">
        <i:Interaction.Behaviors>
            <beh:EventToCommandBehavior Command="{Binding ButtonCommand}" Event="Click" PassArguments="True" />
        </i:Interaction.Behaviors>
    </Button>
    <Button Margin="2" Content="Button 2" Name="btnButton2">
        <i:Interaction.Behaviors>
            <beh:EventToCommandBehavior Command="{Binding ButtonCommand}" Event="Click" PassArguments="True" />
        </i:Interaction.Behaviors>
    </Button>

</StackPanel>

最后像这样创建RelayCommand

public RelayCommand<RoutedEventArgs> ButtonCommand { get; }

ButtonCommand = new RelayCommand<RoutedEventArgs>( x => Foo(x) );

private void Foo( RoutedEventArgs args)
{
    string buttonName = ( ( System.Windows.FrameworkElement )args.Source ).Name;
    //Your switch statements..
}

同样,您还可以附加更多事件,例如MouseEnterMouseLeave