[英]How can I configure the click event handler of a control for removing itself at its object creation?
假设我有两个类: MainWindow
和MainWindowViewModel
。 MainWindow
有一个名为ButtonControl
的控件,带有一个单击事件处理程序,该事件将在MainWindowViewModel
中调用一个函数。 该函数创建图像,然后将其添加到MainWindow中的WrapPanel的子级中。 我想在创建图像控件时为它配置一个click事件处理程序,以便在单击它时可以从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) { }
}
}
}
}
将MainWindow引用传递给ImageCreation方法并在后面的代码中创建UI元素根本不是MVVM。
基本的MVVM解决方案将使用ItemsControl和包含Image元素的ItemTemplate。 ItemsControl的ItemsSource属性绑定到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,该按钮在其ControlTemplate中使用Image元素,并且将其Command属性绑定到视图模型中的ICommand
属性。 该命令将从源集合中删除当前图像。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.