WPF Image scalertransform translatetransform mvvm,custom delegate command CommandManager.RequerySuggested += value;

FredGrit發表於2024-07-02
//xaml
<Window x:Class="WpfApp187.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:WpfApp187"
        mc:Ignorable="d" WindowState="Maximized" 
        Title="" Height="450" Width="800">
    <Grid Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="lbx" Grid.Row="0" Grid.Column="0" SelectedIndex="0"
                 SelectionChanged="lbx_SelectionChanged"                 
                 ItemsSource="{Binding ImgsList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding Content,RelativeSource={RelativeSource AncestorType=ListBoxItem}}" 
                           Width="200" Height="500"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Image x:Name="img" Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
                   Source="{Binding SelectedItem,ElementName=lbx}" ClipToBounds="True"               
         MouseDown="img_MouseDown" MouseMove="Img_MouseMove" MouseUp="Img_MouseUp"
         MouseWheel="Img_MouseWheel">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="scaler"/>
                    <TranslateTransform x:Name="translater"/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
        <DataGrid x:Name="dg" Grid.Row="1" Grid.Column="0" 
                  ItemsSource="{Binding BooksList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    </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;

namespace WpfApp187
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new VM();
            this.DataContext = vm;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {

        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }



        private Point currentPt { get; set; }
        bool isMoving = false;
        private void img_MouseDown(object sender, MouseButtonEventArgs e)
        {
            currentPt = e.GetPosition(img);
        }

        private void Img_MouseMove(object sender, MouseEventArgs e)
        {
            isMoving = true;
        }

        private void Img_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.ButtonState == MouseButtonState.Released && e.ChangedButton == MouseButton.Left && isMoving)
            {
                Point newPt = e.GetPosition(img);
                translater.X += scaler.ScaleX * (newPt.X - currentPt.X);
                translater.Y += scaler.ScaleY * (newPt.Y - currentPt.Y);
                isMoving = false;
            }
        }

        private void Img_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            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(img).X;
            scaler.CenterY = e.GetPosition(img).Y;
        }

        private void lbx_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            scaler.ScaleX = 1.0;
            scaler.ScaleY = 1.0;
            scaler.CenterX = 0;
            scaler.CenterY = 0;
            translater.X = 0;
            translater.Y = 0;
            this.Title = lbx.SelectedItem.ToString();
        }
    }

    public class Book
    {
        public int Id { get; set; }

        public string ImgUrl { get; set; }
    }


    public class DelCmd : ICommand
    {
        private Action<object> _execute;
        private Predicate<object> _canExecute;

        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public DelCmd(Action<object> executeValue, Predicate<object> canExecute)
        {
            _execute = executeValue;
            _canExecute = canExecute;
        }

        public DelCmd(Action<object> executeValue) : this(executeValue, null)
        {
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }
            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }
    }

    public class VM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }

        private List<Book> booksList;
        public List<Book> BooksList
        {
            get
            {
                return booksList;
            }
            set
            {
                if (booksList != value)
                {
                    booksList = value;
                    OnPropertyChanged(nameof(BooksList));
                }
            }
        }

        private List<string> imgsList;
        public List<string> ImgsList
        {
            get
            {
                return imgsList;
            }
            set
            {
                if (value != imgsList)
                {
                    imgsList = value;
                    OnPropertyChanged(nameof(ImgsList));
                }
            }
        }

        public VM()
        {
            BooksList = new List<Book>();
            var imgs = System.IO.Directory.GetFiles(@"..\..\Images");
            if (imgs != null && imgs.Any())
            {
                BooksList = new List<Book>();
                int len = imgs.Count();
                for (int i = 0; i < len; i++)
                {
                    BooksList.Add(new Book()
                    {
                        Id = i + 1,
                        ImgUrl = imgs[i]
                    });
                }
                ImgsList = new List<string>(BooksList.Select(x => x.ImgUrl));
            }
        }
    }

}

相關文章