如果使用command必须要新建一个类实现command接口,然后在viewmodel里使用这个类定义command属性,这个在网上有大量案例所以就不说多少了。
第一种,使用caliburn.micro框架,
<Window
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:partmanager.Views"
xmlns:loc="clr-namespace:partmanager.ViewModels"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Views="clr-namespace:materialtest.Views;assembly=materialtest"
xmlns:ViewModel="clr-namespace:materialtest.ViewModel;assembly=materialtest"
xmlns:cal="http://www.caliburnproject.org"
xmlns:Interaction="http://schemas.microsoft.com/expression/2010/interactions"
x:Class="partmanager.Views.MainView"
mc:Ignorable="d"
Title="MainViewilgjhgv" Height="450" Width="800" x:Name="MyMainView" >
<Menu IsMainMenu="True" x:Name="po">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="MenuItemClick"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<MenuItem Header="文件" Checked="MenuItem_Checked_1" Click="MenuItem_Click_1" >
<!--<MenuItem Header="退出" Click="MenuItem_Click" Checked="MenuItem_Checked_2">
</MenuItem>-->
</MenuItem>
<MenuItem Header="帮助" Command="{Binding Help}" CommandParameter="{Binding}"/>
<MenuItem Header="设置" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="ConfigClick"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
</Menu>
viewmodel页的关联代码是
public void MenuItemClick(object sender, RoutedEventArgs e) {
var menuItem = sender as MenuItem;
if (menuItem == null) return;
}
第二种,
View页代码
<Image x:Name="imageshow" Grid.Column="1" Margin="0" cal:Message.Attach="[Event MouseLeftButtonDown]=[ImageClick($source,$eventArgs)];[Event MouseUp]=[ImageUp($source,$eventArgs)];[Event MouseDown]=[ImageDown($source,$eventArgs)]" Cursor="Hand" Source="/Views/face.png" LayoutUpdated="Image_LayoutUpdated" SourceUpdated="imageshow_SourceUpdated">
</Image>
ViewModel页代码
public void ImageUp(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("鼠标Up");
Rect rc = new Rect(100, 100, 30, 40);
DrawReversibleFrame(rc, Color.FromRgb(255, 255, 0), System.Windows.Forms.FrameStyle.Thick);
}
public void ImageDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("鼠标Down");
Rect rc= new Rect(100,100,30,40);
DrawReversibleFrame(rc,Color.FromRgb(255,255,0), System.Windows.Forms.FrameStyle.Thick);
}
public void ImageClick(object sender, MouseButtonEventArgs e)
{
Console.WriteLine(e.GetPosition(sender as Image).X + "YYY"+ e.GetPosition(sender as Image).Y);
}
第三种,意外情况,使用代理类(当在viewmodel批量生成控件时候(前台必须有控件模板))
可能导致控件的事件无法正常绑定所以有了这个方法
代理类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace YS.Parts.Manager.WPF.Models
{
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
throw new NotImplementedException();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
}
控件窗体:
<UserControl x:Class="YS.Parts.Manager.WPF.Views.ComponentCardView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:YS.Parts.Manager.WPF.Views"
xmlns:localconv="clr-namespace:YS.Parts.Manager.WPF.Converts"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Interaction="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:domain="clr-namespace:YS.Parts.Manager.WPF.Models"
mc:Ignorable="d"
Width="220" MaxHeight="250" VerticalAlignment="Stretch" Cursor=""
MouseDown="UserControl_MouseDown" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="CardDoubleClick"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
<localconv:BoolStringConvert x:Key="boolStringConvert"/>
<localconv:BoolColorConvert x:Key="boolColorConvert"/>
<localconv:StringToImagePath x:Key="convertpath"/>
<Style x:Key="MouseOverHighlightStyle" TargetType="Border">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.300" Storyboard.TargetProperty="BorderBrush.Color" To="Blue"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.300" Storyboard.TargetProperty="BorderBrush.Color" To="Gray"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.Resources>
<domain:BindingProxy x:Key="DataContextProxy" Data="{Binding}"/>
</Grid.Resources>
<Border Style="{StaticResource MouseOverHighlightStyle}" Background="{Binding ComponentAvaliable,Converter={StaticResource boolColorConvert},
Mode=OneWay}" BorderBrush="Gray" BorderThickness="5" Margin="10" CornerRadius="30">
<Border Background="{Binding ComponentGroup,Converter={StaticResource boolColorConvert},Mode=OneWay}" BorderBrush="Gray"
CornerRadius="30">
<Grid Cursor="">
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Image Width="70" Height="70" HorizontalAlignment="Left" Source="{Binding ComponentGroup,Converter={StaticResource convertpath},Mode=OneWay}" materialDesign:ShadowAssist.ShadowDepth="Depth3"
VerticalAlignment="Top" Margin="10 10 0 0" Cursor="Hand" >
</Image>
<StackPanel Orientation="Vertical" Margin="0,3,-3,0" Grid.Column="2">
<Button x:Name="shanchu" Width="60" ToolTip="删除" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" IsEnabled="{Binding DeleteIsEnable}"
Height="40" HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="Hand" Background="{x:Null}" BorderBrush="{x:Null}" Command="{Binding DataContext.Delete,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" CommandParameter="{Binding .}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="EnterCardBtn"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<materialDesign:PackIcon Kind="WindowClose" Foreground="Blue" Height="35" Width="35"
Cursor="" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Normal" FontSize="10" />
</Button>
<Button x:Name="shezhi" Width="60" ToolTip="{Binding Data.mytext,Source={StaticResource DataContextProxy}}" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" IsEnabled="{Binding SetIsEnable}"
Height="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,0,10" Cursor="Hand"
Background="{x:Null}" BorderBrush="{x:Null}" Click="Button_Click_1">
<materialDesign:PackIcon Kind="CogOutline" Foreground="Blue" Height="35" Width="35"
Cursor="" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Normal" FontSize="10" />
</Button>
</StackPanel>
<StackPanel Grid.Column="1" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<TextBlock Margin="0,10" Text="{Binding ComponentAvaliable,Converter={StaticResource boolStringConvert},Mode=OneWay}"
FontSize="18" Foreground="blue" FontWeight="Light"/>
<ToggleButton Margin="0,0" IsChecked="{Binding ComponentAvaliable}" Style="{StaticResource MaterialDesignSwitchToggleButton}"
IsEnabled="{Binding ForbiddenIsEnable}" RenderTransformOrigin="0.5,0.5" Cursor="">
<ToggleButton.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</ToggleButton.RenderTransform>
</ToggleButton>
</StackPanel>
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="3">
<TextBlock x:Name="nameText" Text="{Binding ComponentName}" TextWrapping="Wrap" HorizontalAlignment="Center"
Margin="0,0" TextAlignment="Justify" FontSize="18" Foreground="blue"/>
<StackPanel VerticalAlignment="Top" Margin="0,27,0,0" HorizontalAlignment="Center">
<Expander Background="Transparent" HorizontalAlignment="Center" HorizontalContentAlignment="Center"
Header="功能概述" Foreground="Blue" Cursor="" >
<StackPanel Orientation="Vertical" TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Cursor="" >
<TextBlock Text="{Binding ComponentDescribe}" TextWrapping="Wrap" Margin="9 -10 9 5"/>
</StackPanel>
</Expander>
</StackPanel>
</Grid>
</Grid>
</Border>
</Border>
</Grid>
</UserControl>
ViewModel页:
using Caliburn.Micro;
using MaterialDesignThemes.Wpf.Transitions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace YS.Parts.Manager.WPF.ViewModels
{
public class ComponentCardViewModel:Screen
{
/// <summary>
/// 是否启用
/// </summary>
private bool componentAvaliable;
private ICommand delete;
bool deleteAvaliable=true;
public ComponentCardViewModel()
{
Delete= new MyCommand(DeleteAction, DeleteCanExcu);
}
private bool DeleteCanExcu(object arg)
{
return deleteAvaliable;
}
private void DeleteAction(object obj)
{
Console.WriteLine("20230222臭臭delete");
}
public void CardDoubleClick(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("20230222臭臭双击");
}
public void EnterCardBtn(object sender, System.Windows.Input.MouseEventArgs e)
{
Console.WriteLine("20230222臭臭进入");
}
public TransitionEffect Effact { get; set; }
public string ComponentName { get; set; }
public string ComponentGroup { get; set; }
public string ComponentDescribe { get; set; }
public bool ComponentAvaliable
{
get => componentAvaliable;
set
{
componentAvaliable = value;
NotifyOfPropertyChange(() => ComponentAvaliable);
}
}
public bool DeleteIsEnable { get; set; }
public bool SetIsEnable { get; set; }
public bool ForbiddenIsEnable { get; set; }
public ICommand Delete { get => delete; set => delete = value; }
public void ConfigCommand(object obj) {
Console.WriteLine("20230222臭臭config");
}
public void DeleteCommand(object obj)
{
Console.WriteLine("20230222臭臭delete");
}
}
}
mycommand类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace YS.Parts.Manager.WPF
{
internal class MyCommand : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly Action<object> execAction;
private readonly Func<object, bool> changeFunc;
public MyCommand(Action<object> execAction, Func<object, bool> changeFunc)
{
this.execAction = execAction;
this.changeFunc = changeFunc;
}
public bool CanExecute(object parameter)
{
return this.changeFunc.Invoke(parameter);
}
public void Execute(object parameter)
{
this.execAction.Invoke(parameter);
}
}
}
<UserControl x:Class="YS.Parts.Manager.WPF.Views.ComponentCardView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:YS.Parts.Manager.WPF.Views"
xmlns:localconv="clr-namespace:YS.Parts.Manager.WPF.Converts"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Interaction="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:domain="clr-namespace:YS.Parts.Manager.WPF.Models"
mc:Ignorable="d"
Width="220" MaxHeight="250" VerticalAlignment="Stretch" Cursor=""
MouseDown="UserControl_MouseDown" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="CardDoubleClick"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
<localconv:BoolStringConvert x:Key="boolStringConvert"/>
<localconv:BoolColorConvert x:Key="boolColorConvert"/>
<localconv:StringToImagePath x:Key="convertpath"/>
<Style x:Key="MouseOverHighlightStyle" TargetType="Border">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.300" Storyboard.TargetProperty="BorderBrush.Color" To="Blue"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.300" Storyboard.TargetProperty="BorderBrush.Color" To="Gray"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Border Style="{StaticResource MouseOverHighlightStyle}" Background="{Binding ComponentAvaliable,Converter={StaticResource boolColorConvert},
Mode=OneWay}" BorderBrush="Gray" BorderThickness="5" Margin="10" CornerRadius="30">
<Border Background="{Binding ComponentGroup,Converter={StaticResource boolColorConvert},Mode=OneWay}" BorderBrush="Gray"
CornerRadius="30">
<Grid Cursor="">
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Image Width="70" Height="70" HorizontalAlignment="Left" Source="{Binding ComponentGroup,Converter={StaticResource convertpath},Mode=OneWay}" materialDesign:ShadowAssist.ShadowDepth="Depth3"
VerticalAlignment="Top" Margin="10 10 0 0" Cursor="Hand" >
</Image>
<StackPanel Orientation="Vertical" Margin="0,3,-3,0" Grid.Column="2">
<Button x:Name="shanchu" Width="60" ToolTip="删除" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" IsEnabled="{Binding DeleteIsEnable}"
Height="40" HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="Hand" Background="{x:Null}" BorderBrush="{x:Null}" Command="{Binding DataContext.Delete,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" CommandParameter="{Binding .}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<Interaction:CallMethodAction TargetObject="{Binding}" MethodName="EnterCardBtn"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<materialDesign:PackIcon Kind="WindowClose" Foreground="Blue" Height="35" Width="35"
Cursor="" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Normal" FontSize="10" />
</Button>
<Button x:Name="shezhi" Width="60" ToolTip="设置" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" IsEnabled="{Binding SetIsEnable}"
Height="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,0,10" Cursor="Hand"
Background="{x:Null}" BorderBrush="{x:Null}" Click="Button_Click_1">
<materialDesign:PackIcon Kind="CogOutline" Foreground="Blue" Height="35" Width="35"
Cursor="" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Normal" FontSize="10" />
</Button>
</StackPanel>
<StackPanel Grid.Column="1" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<TextBlock Margin="0,10" Text="{Binding ComponentAvaliable,Converter={StaticResource boolStringConvert},Mode=OneWay}"
FontSize="18" Foreground="blue" FontWeight="Light"/>
<ToggleButton Margin="0,0" IsChecked="{Binding ComponentAvaliable}" Style="{StaticResource MaterialDesignSwitchToggleButton}"
IsEnabled="{Binding ForbiddenIsEnable}" RenderTransformOrigin="0.5,0.5" Cursor="">
<ToggleButton.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</ToggleButton.RenderTransform>
</ToggleButton>
</StackPanel>
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="3">
<TextBlock x:Name="nameText" Text="{Binding ComponentName}" TextWrapping="Wrap" HorizontalAlignment="Center"
Margin="0,0" TextAlignment="Justify" FontSize="18" Foreground="blue"/>
<StackPanel VerticalAlignment="Top" Margin="0,27,0,0" HorizontalAlignment="Center">
<Expander Background="Transparent" HorizontalAlignment="Center" HorizontalContentAlignment="Center"
Header="功能概述" Foreground="Blue" Cursor="" >
<StackPanel Orientation="Vertical" TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Cursor="" >
<TextBlock Text="{Binding ComponentDescribe}" TextWrapping="Wrap" Margin="9 -10 9 5"/>
</StackPanel>
</Expander>
</StackPanel>
</Grid>
</Grid>
</Border>
</Border>
</Grid>
</UserControl>