WPF 事件转命令 EventToCommand 以点击鼠标获取像素坐标为例

事件转命令带参数

控件有时候没有 Command 的情况下可以用事件转命令 EventToCommand 的方案解决。

▲ 鼠标点击获取到图像点击处的像素坐标值。

首先,还是需要额外引入一个程序集(System.Windows.Interactivity.dll)和相应命名空间:

xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

XAML:

<Window.DataContext>
    <local:MainVM/>
</Window.DataContext>

<Grid>

    <StackPanel Orientation="Vertical">
        <Border BorderBrush="Red" BorderThickness="1" Margin="0 20 0 0">
            <Image x:Name="image" Width="1080" Height="460" Source="0.jpg" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonDown">
                        <mvvm:EventToCommand Command="{Binding DoPointCommand}" PassEventArgsToCommand="True"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Image>
        </Border>
        <TextBlock x:Name="txtCoord" Text="{Binding PointInfo, StringFormat='坐标值:\{0\}'}" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 10 0 0"/>
    </StackPanel>

</Grid>

ViewModel:

public class MainVM : ViewModelBase
{
    private string _pointInfo;
    public string PointInfo
    {
        get { return _pointInfo; }
        set { _pointInfo = value; RaisePropertyChanged(() => PointInfo); }
    }

    private RelayCommand<MouseButtonEventArgs> _doPointCommand = null;
    public RelayCommand<MouseButtonEventArgs> DoPointCommand
    {
        get
        {
            if (_doPointCommand == null)
            {
                _doPointCommand = new RelayCommand<MouseButtonEventArgs>(e => DoPoint(e));
            }
            return _doPointCommand;
        }
        set { _doPointCommand = value; }
    }

    private void DoPoint(MouseButtonEventArgs e)
    {
        Image image = e.Source as Image;

        if (image == null)
        {
            return;
        }

        PointInfo = "(X=" + e.GetPosition(image).X.ToString("0") + ", Y=" + e.GetPosition(image).Y.ToString("0") + ")";
    }
}

直接的事件转命令

▲ 切换 Combox 的选项,显示选定项的值。

在不需要传事件原参数的情况下可以直接绑定命令,如:

XAML:

<Window.DataContext>
    <local:MainVM/>
</Window.DataContext>

<Grid>

    <StackPanel Margin="10">
        <TextBlock Text="事件转命令执行" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>
        <DockPanel x:Name="EventToCommand" >
            <StackPanel DockPanel.Dock="Left" Width="240" Orientation="Horizontal" >
                <ComboBox Width="130" ItemsSource="{Binding ResType.List}" DisplayMemberPath="Text" SelectedValuePath="Key" 
                      SelectedIndex="{Binding ResType.SelectIndex}" >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectionChanged">
                            <mvvm:EventToCommand Command="{Binding SelectCommand}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </ComboBox>
            </StackPanel>
            <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal">
                <TextBlock Text="{Binding SelectInfo,StringFormat='选中值:\{0\}'}" ></TextBlock>
            </StackPanel>
        </DockPanel>
    </StackPanel>

</Grid>

Models & ViewModel:

public class ComplexInfoModel : ObservableObject
{
    private String key;
    /// <summary>
    /// Key值
    /// </summary>
    public String Key
    {
        get { return key; }
        set { key = value; RaisePropertyChanged(() => Key); }
    }


    private String text;
    /// <summary>
    /// Text值
    /// </summary>
    public String Text
    {
        get { return text; }
        set { text = value; RaisePropertyChanged(() => Text); }
    }
}

public class ResTypeModel
{
    private Int32 selectIndex;
    /// <summary>
    /// 选中索引
    /// </summary>
    public Int32 SelectIndex
    {
        get { return selectIndex; }
        set { selectIndex = value; }
    }

    private List<ComplexInfoModel> list;
    /// <summary>
    /// 下拉框列表
    /// </summary>
    public List<ComplexInfoModel> List
    {
        get { return list; }
        set { list = value; }
    }
}

public class MainVM : ViewModelBase
{
    public MainVM()
    {
        ResType = new ResTypeModel()
        {
            SelectIndex = 0,
            List = new List<ComplexInfoModel>() {
                new ComplexInfoModel() { Key="0", Text="请选择..." },
                new ComplexInfoModel() { Key="1", Text="苹果" },
                new ComplexInfoModel() { Key="2", Text="香蕉" },
                new ComplexInfoModel() { Key="3", Text="樱桃"} }
        };
    }

    private String selectInfo;
    /// <summary>
    /// 选中信息
    /// </summary>
    public String SelectInfo
    {
        get { return selectInfo; }
        set { selectInfo = value; RaisePropertyChanged(() => SelectInfo); }
    }

    private ResTypeModel resType;
    /// <summary>
    /// 资源类型列表
    /// </summary>
    public ResTypeModel ResType
    {
        get { return resType; }
        set { resType = value; RaisePropertyChanged(() => ResType); }
    }


    private RelayCommand selectCommand;
    /// <summary>
    /// 事件转命令执行
    /// </summary>
    public RelayCommand SelectCommand
    {
        get
        {
            if (selectCommand == null)
                selectCommand = new RelayCommand(() => ExecuteSelect());
            return selectCommand;
        }
        set { selectCommand = value; }
    }
    private void ExecuteSelect()
    {
        if (ResType != null && ResType.SelectIndex > 0)
        {
            SelectInfo = ResType.List[ResType.SelectIndex].Text;
        }
    }
}



posted @   double64  阅读(1303)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示