在程序中,我使用图片框创建了多个面板。图片框被委托为可点击。我想让用户可以选择从订单中删除其中一个面板/图片框。现在,如果它被删除并且订单被重新排列,那么被删除的图片框之后的所有图片框都会保留其委托订单。所以在删除它之后点击它们中的任何一个,跳到它旁边的那个(即点击#9,它将转到#10)。我需要删除重新排序的委托并重新委托它们。我试过了:
int z2 = z;
var myClickDelegate = (EventHandler)delegate { clicked(z2, null); };
PicBx[z].Click += myClickDelegate;
创建和
PicBx[z].Click -= myClickDelegate;
删除
以及
int z2 = z;
PicBx[z].Click -= delegate { clicked(z2, null); };
但他们都没有删除原始授权。
答案 0 :(得分:1)
你的第一种方法应该有用,但后一种方法不适用
因为当您执行PicBx[z].Click -= delegate { clicked(z2, null); };
方法时,您不会删除旧委托,而是创建新委托,然后将其删除。
在第一次尝试时,这应该有效:
private void SomeMethod()
{
var myClickDelegate = (EventHandler)delegate { clicked(z2, null); };
PicBx[z].Click += myClickDelegat;
//Do extra work
PicBx[z].Click -= mayClickDelegat;
}
编辑:对评论进行配对:
我注意到你只是在你的委托添加clicked(z2, null)
,所以我假设你只是在第一个位置创建委托只是为了传递int z2
来表示图片框索引。
您可以使用pictureBox.Tag
将该索引与图片框本身放在一起,然后在点击事件中从标记中获取int
:
int z2 = z;
picBx[z].Tag = z2;//here we embedded the number with the picture box.
PicBx[z].Click += clicked;
...
PicBx[z].Click -= clicked;
在点击的事件中如此:
private void clicked(object sender, EventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if (pictureBox != null)
{
int number = Convert.ToInt32(pictureBox.Tag);
...
}
}
Edit2:作为评论的配对,您似乎对clicked
方法有不同的签名:
private void clicked(int tes,..
{
Pnl[tes].BackColor = Color.Red;
}
这里我们只将其改为:
private void clicked(object sender, EventArgs e)
{
PictureBox pictureBox = sender as PictureBox;//when user clicks on picture box it will be the sender parameter.
if (pictureBox != null)
{
//we add number to each of picture boxes at there tags. "picBx[z].Tag = z2"
int tes = Convert.ToInt32(pictureBox.Tag);
pnl[tes].BackColor = Color.Red;
}
}
答案 1 :(得分:1)
您不是要删除同一个委托。你应该尝试将你的代表存储在某个地方:
this.MyDelegate = delegate { clicked(z2, null); };
PicBx[z].Click += this.MyDelegate;
...
...
PicBx[z].Click -= this.MyDelegate;
但与这样的代表一起玩会导致糟糕的设计选择。您应该定义一个bool
,您可以在其中确定是否执行了您的委托。
public void OnClick(object sender, ...)
{
if(myBool)
{
...
}
}
答案 2 :(得分:0)
从你的评论到Jalal回答,看起来你可能真的需要这样的东西
答案 3 :(得分:0)
这里有两个问题。
正如其他人所指出的那样,第一个是你需要删除你添加到事件处理程序的同一个委托实例。
第二个是你使用数组来存储你的图片框,你的处理程序正在使用索引来查找你的图片框,所以当你从数组中删除一个图片框时,所有的图片框的事件处理程序都在数组会指向错误的图片框。
以下是该做什么:
步骤1:更改事件处理程序以获取图片框的实例,而不是数组的索引。
步骤2:创建一个类级别字典,通过图片框保存您的委托引用:
Dictionary<PictureBox, EventHandler> _pictureBoxHandlers =
new Dictionary<PictureBox, EventHandler>();
第3步:编写您的订阅代码:
//After the picture box is added to `PicBx`
var pb = PicBx[z];
var myClickDelegate = (EventHandler)delegate { clicked(pb, null); };
_pictureBoxHandlers[pb] = myClickDelegate;
pb.Click += myClickDelegate;
第4步:写下你的取消订阅代码:
//Before the picture box is removed from `PicBx`
var pb = PicBx[z];
if (_pictureBoxHandlers.ContainsKey(pb))
{
var myClickDelegate = _pictureBoxHandlers[pb];
pb.Click -= myClickDelegate;
_pictureBoxHandlers.Remove(pb);
}
看看情况如何。