[英]The incorrect pictures are being removed
When I click the Delete Selected button, the wrong picture is being deleted. 当我单击“删除所选”按钮时,正在删除错误的图片。 Most of the times it deleted the picture on the right of a selected picture. 大多数时候它删除了所选图片右侧的图片。 Other times, for example when everything is selected, it only deletes a single picture. 其他时间,例如,当选择所有内容时,它仅删除单个图片。
I don't know what's going on. 我不知道发生了什么事。 Here's a picture to illustrate what happens: 这是一张图片来说明会发生什么:
Here is the code for both user controls I'm using: HorizontalPictureScroller and SelectablePicture. 以下是我正在使用的两个用户控件的代码:HorizontalPictureScroller和SelectablePicture。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ComponentModel.Design.Serialization;
namespace WinformsPlayground
{
public partial class HorizontalPictureScroller : UserControl
{
public HorizontalPictureScroller()
{
InitializeComponent();
Pictures = new ObservableCollection<SelectablePicture>();
Pictures.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Pictures_CollectionChanged);
}
#region "Properties"
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ObservableCollection<SelectablePicture> Pictures { get; set; }
private int PositionControlX = 0;
#endregion
#region "Methods"
private void RedrawPictures()
{
PositionControlX = 0;
foreach (var picture in Pictures)
{
picture.Location = new Point(PositionControlX + panelPicturesWrapper.AutoScrollPosition.X, 0);
PositionControlX += 130;
panelPicturesWrapper.Controls.Add(picture);
}
}
public void AddPicture(SelectablePicture picture)
{
Pictures.Add(picture);
}
public void RemovePicture(SelectablePicture picture)
{
Pictures.Remove(picture);
}
public void MovePictureLeft(int index)
{
SelectablePicture tmpPicture = Pictures[index];
Pictures[index] = Pictures[index - 1];
Pictures[index - 1] = tmpPicture;
}
public void MovePictureRight(int index)
{
SelectablePicture tmpPicture = Pictures[index];
Pictures[index] = Pictures[index + 1];
Pictures[index + 1] = tmpPicture;
}
public void SelectAllImages()
{
foreach (var picture in panelPicturesWrapper.Controls)
{
((SelectablePicture)picture).SelectPicture();
}
}
public void DeselectAllImages()
{
foreach (var picture in panelPicturesWrapper.Controls)
{
((SelectablePicture)picture).DeselectPicture();
}
}
public void DeleteSelectedImages()
{
foreach (var picture in panelPicturesWrapper.Controls)
{
if (((SelectablePicture)picture).IsSelected())
{
this.RemovePicture((SelectablePicture)picture);
}
}
}
#endregion
#region "Events"
void Pictures_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RedrawPictures();
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization;
namespace WinformsPlayground
{
public partial class SelectablePicture : UserControl
{
public SelectablePicture()
{
InitializeComponent();
panel1.BackgroundImageLayout = ImageLayout.Zoom;
}
public SelectablePicture(Image image)
{
InitializeComponent();
panel1.BackgroundImage = image;
panel1.BackgroundImageLayout = ImageLayout.Zoom;
}
#region "Properties"
public Image Image()
{
return panel1.BackgroundImage;
}
public bool IsSelected()
{
return chkSelected.Checked;
}
#endregion
#region "Methods"
public void ToggleCheckBox()
{
chkSelected.Checked = chkSelected.Checked ? false : true;
}
public void VisuallySelect()
{
this.BackColor = Color.FromArgb(51, 153, 255);
}
public void VisuallyDeselect()
{
//If none of the controls inside the usercontrol have focus, set this control to white.
if (!this.Focused && !this.panel1.Focused && !this.chkSelected.Focused)
{
this.BackColor = Color.White;
}
}
public void SelectPicture()
{
this.chkSelected.Checked = true;
}
public void DeselectPicture()
{
this.chkSelected.Checked = false;
}
#endregion
#region "Events"
private void panel1_Click(object sender, EventArgs e)
{
VisuallySelect();
ToggleCheckBox();
panel1.Focus();
}
private void chkSelected_Click(object sender, EventArgs e)
{
VisuallySelect();
ToggleCheckBox();
chkSelected.Focus();
}
private void SelectablePicture_Click(object sender, EventArgs e)
{
VisuallySelect();
ToggleCheckBox();
this.Focus();
}
private void panel1_Leave(object sender, EventArgs e)
{
VisuallyDeselect();
}
private void chkSelected_Leave(object sender, EventArgs e)
{
VisuallyDeselect();
}
private void SelectablePicture_Leave(object sender, EventArgs e)
{
VisuallyDeselect();
}
#endregion
}
}
The code is simple enough. 代码很简单。 I've used breakpoints and I can confirm that the HorizontalPictureScroller.DeleteSelectedImages() method is correctly iterating through selected pictures. 我使用了断点,我可以确认HorizontalPictureScroller.DeleteSelectedImages()方法是否正确迭代选定的图片。 I'm not sure what else I could do to see what's going on. 我不确定我还能做些什么来看看发生了什么。 I'm stumped! 我很难过!
Any ideas? 有任何想法吗? Maybe the .Remove() method that comes with the ObservableCollection type doesn't work as I thought it did. 也许ObservableCollection类型附带的.Remove()方法不能像我想象的那样工作。
Every time the Pictures collection changes, you're calling RedrawPictures. 每次图片集合发生变化时,您都会调用RedrawPictures。 That adds all of the pictures again, but doesn't clear anything... so you'll be trying to add a control to panelPicturesWrapper.Controls
when it already contains that control. 这会再次添加所有图片,但不会清除任何内容......所以当它已经包含该控件时,您将尝试向panelPicturesWrapper.Controls
添加一个控件。 That sounds like a bad idea to me. 对我来说,这听起来像个坏主意。
Further, you're iterating over the Controls
collection while changing it, which is generally a bad idea. 此外,您在更改Controls
时会迭代Controls
集合,这通常是一个坏主意。
I suggest you change your removal code to something like this: 我建议您将删除代码更改为以下内容:
public void DeleteSelectedImages()
{
var picturesToRemove = panelPicturesWrapper.Controls
.Cast<SelectablePicture>();
.Where(p => p.IsSelected())
.ToList();
foreach (var picture in picturesToRemove)
{
RemovePicture(picture);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.