2010-11-30 15 views
0

[選択したアイテムを削除]ボタンをクリックすると、間違った画像が削除されています。ほとんどの場合、選択した画像の右側の画像が削除されました。たとえば、すべてが選択されている場合などは、1つの画像だけが削除されます。不適切な画像が削除されています

私は何が起こっているのか分かりません。ここで

alt text

を私が使用している両方のユーザーコントロールのコードです:ここでは何が起こるかを説明する絵だHorizo​​ntalPictureScrollerと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   
    } 
} 

コードは簡単です。私はブレークポイントを使用して、Horizo​​ntalPictureScroller.DeleteSelectedImages()メソッドが選択されたピクチャを正しく反復していることを確認できます。私は何が起こっているか見るために他に何ができるのか分からない。私は困惑している!

アイデア?おそらくObservableCollection型に付属している.Remove()メソッドは、私が思ったように機能しません。

+0

あなたがから項目を削除している同じコレクションを反復処理していますか?私はそのような場合にC#が何をするのかは分かりませんが、恐ろしい音が聞こえます。 –

+0

D'OH!どうやってやるの。あなたが反復しているコレクションを変更することは絶対に避けてください。* –

+0

Pictures.Remove(画像)のコードを投稿できますか? – w69rdy

答えて

2

ピクチャコレクションが変更されるたびに、RedrawPicturesが呼び出されます。これで、すべての画像が再び追加されますが、何もクリアされません...そのコントロールが既に含まれている場合は、panelPicturesWrapper.Controlsにコントロールを追加しようとしています。それは私にとっては悪い考えです。

さらに、Controlsコレクションを変更しながら繰り返していますが、これは一般的には悪い考えです。

私はあなたの削除コードは、このような何かに変更を提案:

public void DeleteSelectedImages() 
{ 
    var picturesToRemove = panelPicturesWrapper.Controls 
               .Cast<SelectablePicture>(); 
               .Where(p => p.IsSelected()) 
               .ToList(); 

    foreach (var picture in picturesToRemove) 
    { 
     RemovePicture(picture); 
    } 
} 
+0

助けてくれてありがとうございます!Linqを使っているあなたのソリューションは理にかなっていますし、ブレークポイントを使って実行すると、実際に選択されているピクチャが抽出されていることがわかります。私が改善することができるものについてのアイデアは?コンピュータは私が言っていることをやっているだけですが、それは理解していますが、picturesToRemoveコレクションの画像を削除する必要があります!D –

+1

@Serg:私の答えの他の部分に対処しました。ここでは、コントロールを複数回追加していると言いますが、RedrawPicturesで既存のコントロールをクリアしましたか? –

+0

はい、バグ。私は最初から削除されていないコントロールを追加していました。ヘルプマンにもう一度感謝します。 :D –

関連する問題