Как настроить обработчик события click элемента управления для удаления самого себя при создании объекта? - PullRequest
0 голосов
/ 02 июля 2019

Предположим, у меня есть два класса: MainWindow и MainWindowViewModel. В MainWindow есть элемент управления ButtonControl с обработчиком события щелчка, который вызывает функцию в MainWindowViewModel. Функция создает изображения, а затем добавляет их к некоторым дочерним элементам WrapPanel в главном окне. Я хочу настроить обработчик события щелчка для элементов управления изображением во время их создания, чтобы можно было удалять элементы управления из MainWindow при нажатии на него (MouseLeftButtonUp). Как я могу это сделать?

MainWindow.xaml

<Windows ...>
<Grid>
<Button Name="ButtonControl" Click="ButtonControl_Click" />
<WrapPanel Name="AttachedPhotosWP" />
</Grid>
</Windows>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    private MainWindowViewModel _vm = new MainWindowViewModel();
    public MainWindowViewModel VM{ get { return _vm; } set { _vm= value; } }
    public MainWindow()
    {
       InitializeComponent();
       this.DataContext = VM;      
    }
    private void ButtonControl_Click(object sender, MouseButtonEventArgs e)
    {
        VM.ImageCreation(this);
    }
}

MainWindowViewModel.cs

public class MainWindowViewModel
{
    /* Some other codes */


    public void ImageCreation(MainWindow MW)
    {
         OpenFileDialog openFileDialog = new OpenFileDialog();
         openFileDialog.Multiselect = true;
         openFileDialog.Title = "Select Images...";
         if (openFileDialog.ShowDialog() == true)
         {
              foreach (var file in openFileDialog.FileNames)
              {
                  try
                  {
                      Image img = new Image();
                      BitmapImage imgSrc = new BitmapImage();
                      imgSrc.BeginInit();
                      Uri fileUri = new Uri(file, UriKind.Absolute);
                      imgSrc.UriSource = fileUri;
                      imgSrc.DecodePixelWidth = 100;
                      imgSrc.CacheOption = BitmapCacheOption.OnLoad;
                      imgSrc.EndInit();
                      img.Source = imgSrc;
                      img.Stretch = Stretch.Uniform;
                      img.Height = 70;
                      img.Margin = new Thickness(4, 4, 4, 4);
                      img.MouseLeftButtonUp += ????
                      img.Cursor = Cursors.Hand;
                      MW.AttachedPhotosWP.Children.Add(img);
                  }
                  catch (SecurityException ex) { }
                  catch (Exception ex) { }     
              }
          }
    }

}

1 Ответ

0 голосов
/ 02 июля 2019

Передача ссылки MainWindow в метод ImageCreation и создание элементов пользовательского интерфейса в коде не совсем MVVM.

Базовое решение MVVM будет использовать ItemsControl с ItemTemplate, который содержит элемент Image. Свойство ItemsSource ItemsControl привязано к ObservableCollection<ImageSource>. Элемент Image имеет обработчик событий, который удаляет себя из этой коллекции.

<ItemsControl ItemsSource="{Binding ImageFiles}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"
                   Height="70" Margin="4"
                   MouseLeftButtonUp="Image_MouseLeftButtonUp"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
...
<Button Content="Load Images..." Click="LoadButton_Click"/>

Класс MainWindow и модель представления будут выглядеть так:

public partial class MainWindow : Window
{
    private readonly ViewModel viewModel = new ViewModel();

    public MainWindow()
    {
        DataContext = viewModel;
        InitializeComponent();
    }

    private void LoadButton_Click(object sender, RoutedEventArgs e)
    {
        var openFileDialog = new OpenFileDialog();
        openFileDialog.Multiselect = true;
        openFileDialog.Title = "Select Images...";
        openFileDialog.Filter = "JPEG Files (*.jpg)|*.jpg|PNG Files (*.png)|*.png";

        if (openFileDialog.ShowDialog() == true)
        {
            viewModel.LoadImages(openFileDialog.FileNames);
        }
    }

    private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        var image = (Image)sender;
        viewModel.ImageFiles.Remove(image.Source);
    }
}

public class ViewModel
{
    public ObservableCollection<ImageSource> ImageFiles { get; }
        = new ObservableCollection<ImageSource>();

    public void LoadImages(IEnumerable<string> imageFiles)
    {
        ImageFiles.Clear();

        foreach (var imageFile in imageFiles)
        {
            var image = new BitmapImage();
            image.BeginInit();
            image.UriSource = new Uri(imageFile, UriKind.RelativeOrAbsolute);
            image.DecodePixelWidth = 100;
            image.EndInit();
            ImageFiles.Add(image);
        }
    }
}

Вы можете еще улучшить это, заменив Image обработчиком события мыши на Button, которая использует элемент Image в своем ControlTemplate и имеет свойство Command, связанное со свойством ICommand в вашей модели представления. Эта команда удалит текущее изображение из исходной коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...