如何在 MVVM WPF(c#) 中编写这些特定行?
How to write these particular lines in MVVM WPF(c#)?
.
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 写这些行..提前致谢
我想,这个适合你
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>
在这里您需要 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
参数传递给您的命令,如下所示:
<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..
}
同样,您还可以附加更多事件,例如 MouseEnter
或 MouseLeave
.
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 写这些行..提前致谢
我想,这个适合你
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>
在这里您需要 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
参数传递给您的命令,如下所示:
<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..
}
同样,您还可以附加更多事件,例如 MouseEnter
或 MouseLeave