//xaml <Window x:Class="WpfApp201.MainWindow" 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:behavior="http://schemas.microsoft.com/xaml/behaviors" xmlns:local="clr-namespace:WpfApp201" mc:Ignorable="d" WindowState="Maximized" Title="{Binding MainTitle,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="450" Width="800"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ListBox x:Name="lbx" Grid.Column="0" ItemsSource="{Binding BooksList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding SelectedIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedBook,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding ImgUrl}" Width="200" Height="500" RenderOptions.BitmapScalingMode="LowQuality"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Image x:Name="img" Grid.Column="1" Source="{Binding SelectedItem.ImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ElementName=lbx}" ClipToBounds="True"> <behavior:Interaction.Triggers> <behavior:EventTrigger EventName="MouseWheel"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="Image_MouseWheel"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseDown"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseDown"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseUp"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseUp"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseMove"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseMove"/> </behavior:EventTrigger> </behavior:Interaction.Triggers> <Image.RenderTransform> <TransformGroup> <ScaleTransform /> <TranslateTransform /> </TransformGroup> </Image.RenderTransform> </Image> </Grid> </Window> //cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; namespace WpfApp201 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var vm = new BookVM(); this.DataContext = vm; } } public class BookVM : INotifyPropertyChanged { public BookVM() { InitData(); InitTimer(); } private void InitTimer() { System.Timers.Timer tm = new System.Timers.Timer(); tm.Elapsed += Tm_Elapsed; tm.Interval = 100; //tm.Start(); } private void Tm_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (++SelectedIdx >= BooksList.Count) { SelectedIdx = 0; } } private void InitData() { var imgsList = Directory.GetFiles(@"..\..\Images"); if (imgsList != null && imgsList.Any()) { BooksList = new List<Book>(); int len = imgsList.Count(); for (int i = 0; i < 100000; i++) { BooksList.Add(new Book() { Id = i + 1, ImgUrl = imgsList[i % len] }); } SelectedBook = BooksList[0]; } } public void img_MouseDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image != null) { CurrentPt = e.GetPosition(image); } } public void img_MouseUp(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image != null && isMoving && e.ChangedButton == MouseButton.Left && e.ButtonState == MouseButtonState.Released) { var transformGroup = image.RenderTransform as TransformGroup; if (transformGroup != null) { foreach (var child in transformGroup.Children) { var translater = child as TranslateTransform; if (translater != null) { var pt = e.GetPosition(image); translater.X += pt.X - CurrentPt.X; translater.Y += pt.Y - CurrentPt.Y; break; } } } } } public void img_MouseMove(object sender, MouseEventArgs e) { var image = sender as Image; if (image != null) { isMoving = true; } } public void Image_MouseWheel(object sender, MouseWheelEventArgs e) { //new System.Linq.SystemCore_EnumerableDebugView<System.Windows.Media.Transform>(((System.Windows.Media.TransformGroup)image.RenderTransform).Children).Items[0] var image = sender as Image; if (image != null) { var transformGroup = image.RenderTransform as TransformGroup; if (transformGroup != null) { foreach (var child in transformGroup.Children) { var scaler = child as ScaleTransform; if (scaler != null) { if (e.Delta > 0) { scaler.ScaleX *= 1.2; scaler.ScaleY *= 1.2; } else { scaler.ScaleX /= 1.2; scaler.ScaleY /= 1.2; } scaler.CenterX = e.GetPosition(image).X; scaler.CenterY = e.GetPosition(image).Y; break; } } } } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private bool isMoving = false; private Point currentPt; public Point CurrentPt { get { return currentPt; } set { if (value != currentPt) { currentPt = value; OnPropertyChanged(nameof(CurrentPt)); } } } private int selectedIdx; public int SelectedIdx { get { return selectedIdx; } set { if (value != selectedIdx) { selectedIdx = value; OnPropertyChanged(nameof(SelectedIdx)); } } } private Book selectedBook; public Book SelectedBook { get { return selectedBook; } set { if (value != selectedBook) { selectedBook = value; OnPropertyChanged(nameof(SelectedBook)); MainTitle = SelectedBook?.ToString(); } } } private List<Book> booksList; public List<Book> BooksList { get { return booksList; } set { if (value != booksList) { booksList = value; OnPropertyChanged(nameof(BooksList)); } } } private string mainTitle; public string MainTitle { get { return mainTitle; } set { mainTitle = value; OnPropertyChanged(nameof(MainTitle)); } } } public class Book { public int Id { get; set; } public string ImgUrl { get; set; } public override string ToString() { return $"{Id},{System.IO.Path.GetFullPath(ImgUrl)}"; } } }
Key part
<Image x:Name="img" Grid.Column="1" Source="{Binding SelectedItem.ImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ElementName=lbx}" ClipToBounds="True"> <behavior:Interaction.Triggers> <behavior:EventTrigger EventName="MouseWheel"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="Image_MouseWheel"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseDown"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseDown"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseUp"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseUp"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseMove"> <behavior:CallMethodAction TargetObject="{Binding}" MethodName="img_MouseMove"/> </behavior:EventTrigger> </behavior:Interaction.Triggers> <Image.RenderTransform> <TransformGroup> <ScaleTransform /> <TranslateTransform /> </TransformGroup> </Image.RenderTransform> </Image>
public void img_MouseDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image != null) { CurrentPt = e.GetPosition(image); } } public void img_MouseUp(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image != null && isMoving && e.ChangedButton == MouseButton.Left && e.ButtonState == MouseButtonState.Released) { var transformGroup = image.RenderTransform as TransformGroup; if (transformGroup != null) { foreach (var child in transformGroup.Children) { var translater = child as TranslateTransform; if (translater != null) { var pt = e.GetPosition(image); translater.X += pt.X - CurrentPt.X; translater.Y += pt.Y - CurrentPt.Y; break; } } } } } public void img_MouseMove(object sender, MouseEventArgs e) { var image = sender as Image; if (image != null) { isMoving = true; } } public void Image_MouseWheel(object sender, MouseWheelEventArgs e) { //new System.Linq.SystemCore_EnumerableDebugView<System.Windows.Media.Transform>(((System.Windows.Media.TransformGroup)image.RenderTransform).Children).Items[0] var image = sender as Image; if (image != null) { var transformGroup = image.RenderTransform as TransformGroup; if (transformGroup != null) { foreach (var child in transformGroup.Children) { var scaler = child as ScaleTransform; if (scaler != null) { if (e.Delta > 0) { scaler.ScaleX *= 1.2; scaler.ScaleY *= 1.2; } else { scaler.ScaleX /= 1.2; scaler.ScaleY /= 1.2; } scaler.CenterX = e.GetPosition(image).X; scaler.CenterY = e.GetPosition(image).Y; break; } } } } }
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using System.Windows; namespace Microsoft.Xaml.Behaviors.Core; public class CallMethodAction : TriggerAction<DependencyObject> { private class MethodDescriptor { public MethodInfo MethodInfo { get; private set; } public bool HasParameters => Parameters.Length != 0; public int ParameterCount => Parameters.Length; public ParameterInfo[] Parameters { get; private set; } public Type SecondParameterType { get { if (Parameters.Length >= 2) { return Parameters[1].ParameterType; } return null; } } public MethodDescriptor(MethodInfo methodInfo, ParameterInfo[] methodParams) { MethodInfo = methodInfo; Parameters = methodParams; } } private List<MethodDescriptor> methodDescriptors; public static readonly DependencyProperty TargetObjectProperty = DependencyProperty.Register("TargetObject", typeof(object), typeof(CallMethodAction), new PropertyMetadata(OnTargetObjectChanged)); public static readonly DependencyProperty MethodNameProperty = DependencyProperty.Register("MethodName", typeof(string), typeof(CallMethodAction), new PropertyMetadata(OnMethodNameChanged)); public object TargetObject { get { return GetValue(TargetObjectProperty); } set { SetValue(TargetObjectProperty, value); } } public string MethodName { get { return (string)GetValue(MethodNameProperty); } set { SetValue(MethodNameProperty, value); } } private object Target => TargetObject ?? base.AssociatedObject; public CallMethodAction() { methodDescriptors = new List<MethodDescriptor>(); } protected override void Invoke(object parameter) { if (base.AssociatedObject == null) { return; } MethodDescriptor methodDescriptor = FindBestMethod(parameter); if (methodDescriptor != null) { ParameterInfo[] parameters = methodDescriptor.Parameters; if (parameters.Length == 0) { methodDescriptor.MethodInfo.Invoke(Target, null); } else if (parameters.Length == 2 && base.AssociatedObject != null && parameter != null && parameters[0].ParameterType.IsAssignableFrom(base.AssociatedObject.GetType()) && parameters[1].ParameterType.IsAssignableFrom(parameter.GetType())) { methodDescriptor.MethodInfo.Invoke(Target, new object[2] { base.AssociatedObject, parameter }); } } else if (TargetObject != null) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionStringTable.CallMethodActionValidMethodNotFoundExceptionMessage, MethodName, TargetObject.GetType().Name)); } } protected override void OnAttached() { base.OnAttached(); UpdateMethodInfo(); } protected override void OnDetaching() { methodDescriptors.Clear(); base.OnDetaching(); } private MethodDescriptor FindBestMethod(object parameter) { if (parameter != null) { parameter.GetType(); } return methodDescriptors.FirstOrDefault((MethodDescriptor methodDescriptor) => !methodDescriptor.HasParameters || (parameter != null && methodDescriptor.SecondParameterType.IsAssignableFrom(parameter.GetType()))); } private void UpdateMethodInfo() { methodDescriptors.Clear(); if (Target == null || string.IsNullOrEmpty(MethodName)) { return; } MethodInfo[] methods = Target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo method in methods) { if (IsMethodValid(method)) { ParameterInfo[] methodParams = method.GetParameters(); if (AreMethodParamsValid(methodParams)) { methodDescriptors.Add(new MethodDescriptor(method, methodParams)); } } } methodDescriptors = methodDescriptors.OrderByDescending(delegate(MethodDescriptor methodDescriptor) { int num = 0; if (methodDescriptor.HasParameters) { Type type = methodDescriptor.SecondParameterType; while (type != typeof(EventArgs)) { num++; type = type.BaseType; } } return methodDescriptor.ParameterCount + num; }).ToList(); } private bool IsMethodValid(MethodInfo method) { if (!string.Equals(method.Name, MethodName, StringComparison.Ordinal)) { return false; } if (method.ReturnType != typeof(void)) { return false; } return true; } private static bool AreMethodParamsValid(ParameterInfo[] methodParams) { if (methodParams.Length == 2) { if (methodParams[0].ParameterType != typeof(object)) { return false; } if (!typeof(EventArgs).IsAssignableFrom(methodParams[1].ParameterType)) { return false; } } else if (methodParams.Length != 0) { return false; } return true; } private static void OnMethodNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { ((CallMethodAction)sender).UpdateMethodInfo(); } private static void OnTargetObjectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { ((CallMethodAction)sender).UpdateMethodInfo(); } }
标签:via,MouseWheel,mvvm,image,System,var,using,null,public From: https://www.cnblogs.com/Fred1987/p/18291451