WPF ListBox itemTemplate和Button按下事件 [英] WPF ListBox itemtemplate and Button press events

查看:577
本文介绍了WPF ListBox itemTemplate和Button按下事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

这是一个棘手的问题.我有保存X数量的数据类的列表框.我代表我的数据类通过列表框itemtemplate,其中包含文本块,图片和按钮. listBox_SelectionChanged事件(仅在单击某些列表框项目时开始)将启动使用列表框所选项目数据类作为参数的过程.效果很好!

但是这里出现了一个棘手的问题,例如我说过我的列表框项目模板中有按钮,因此每个列表框项目都有一个按钮,该按钮应以该项目作为参数按下该项目来启动其他任务.我怎么做?通常,在按钮单击事件中,我只是选择listboxitem,然后按其按钮,但是现在我无法按listbox项目,因为它会触发与按钮事件不同的任务.

有点怪异的情况,但我希望你有主意:)

干杯!

Hi all!

Here is tricky question. I have listbox which hold X quantity of my dataclasses. I represents my dataclasses trough listbox itemtemplate which contains textblocks, picture and button. listBox_SelectionChanged event (starts when you just click some listbox item) starts process which uses listbox selected item dataclass as parameter. Works just fine!

But here it comes the tricky question, like I said I have button in my listbox itemtemplate so every listbox item has button which should start different task with that item which button was pressed as parameter. How do I do that? Normally with button click events I just chooce listboxitem and then I press its button but now I cant press listbox item because it will fire different task than my button event.

Kinda weird situation, but I hope you got idea :)

Cheers!

推荐答案

在这种情况下,没有什么奇怪的.为了进一步告诉您,CodeProject这里有很多非常相似的问题.这个话题实际上是最受欢迎的话题之一.难怪这种情况很自然.

现在,可以有不同的解决方案,但是根本没有棘手的问题.
这是我认为足够强大的一种方法.另一个好处:它可以与两者 WPF和System.Windows.Forms一起使用.

(您需要唯一地标识按钮.许多建议使用名称甚至按钮文本.请不要这样做!这不是可支持的方法.)

与其尝试识别按钮,不如在按钮标签中添加一些信息.它应该是我们在单击时使用的一些信息,并且可以是任何信息:枚举(采取何种操作),结构或类(单击时使用的数据,例如数据库密钥或其他) :

There is nothing weird in this situation. To tell you more, there are many very similar questions here at CodeProject; this topic is actually one of the popular ones. No wonder, this situation is very natural.

Now, there can be different solutions, but there is nothing tricky at all.
Here is one of the ways which I think is robust enough. Another good thing: it can be used with both WPF and System.Windows.Forms.

(You need to uniquely identify the button. Many advise to use the name or even button text. Please, never do that! It is not a supportable way.)

Instead of attempting to identify a button, put some information in its tag. It should be some information we use at the moment of click, and can be anything: enumeration (what kind of action to take), a structure or a class (data used at the moment of click, such as database key or what ever):

internal class ButtonClickInfo {
    internal ButtonClickInfo(/*...*/) { /*...*/ }
    //...
}



现在,为每个按钮添加一个适当的这种类型的实例和适当的处理程序:



Now, for every button, add an appropriate instance of this type and appropriate handler:

Button btn;

//...

btn.Tag = new ButtonClickInfo(//... different parameters for each button
btn.Click += (sender, eventArgs) => {
    Button thisButton = (Button)sender; //not need in "as": you defined it as a button 2 lines above
    ButtonClickInfo info = (ButtonClickInfo)(thisButton.Tag); //same thing, cast with no worries
    PerformButtonClickActionDependingOnButtonClickInfo(info); //whatever you want, one method for all buttons
};



您可以自动设置标签和Click事件处理程序的此过程:参数化传递给标签的数据(这应该是按钮之间的唯一区别),并根据项目数据等以某种循环运行它.

现在,请注意:多亏了匿名委托,您不必将任何未使用的参数(如sendereventArgs)传递给处理程序方法;您已经从Button实例中提取了ButtonClickInfo实例,这很重要.您仅将基本数据传递给PerformButtonClickActionDependingOnButtonClickInfo.因此,我不建议使用Designed自动生成的任何事件处理程序:它会生成很难支持的过时样式代码.通过以上面我演示的方式进行编码,可以更快,更好地实现可支持性.

—SA



You can automate this procedure of setting Tags and Click event handlers: parametrize the data passed to tag (this should be the only difference between buttons) and run it in some loop, depending on item data, etc.

Now, pay attention: thanks to the anonymous delegate, you do not have to pass any of the unused parameters like sender and eventArgs to the handler method; you already extracted ButtonClickInfo instance from the Button instance, and this is all what matters. You pass only essential data to PerformButtonClickActionDependingOnButtonClickInfo. Therefore, I don''t recomment using any event handlers auto-generated by the Designed: it will generate obsolete-style code which is hard to support. Doing it by coding the way I illustrated above is much faster and better for supportability.

—SA




如果我理解正确的话.您的列表框中有很多项目,每个项目中都有一个按钮.您想获得单击了按钮的对象.

我会提出两种选择:

首先,您可以从发送方获取DataContext并将其强制转换为您的Object.
Hi,

if I understand correctly. You have many items in your listbox and in every item is a button. And you want to get the object on which you have clicked the Button.

I would propose two options:

First you could get the DataContext from the sender and cast it to your Object.
MyClass my = (sender as Button).DataContext as MyClass; 



其次,您可以使用RelayCommand.看看这些文章:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030 [^ ]
http://stackoverflow.com/questions/862570/relaycommand-in-wpf [ ^ ]


希望对您有帮助



Second your could use RelayCommand. Look at these Articles:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030[^]
http://stackoverflow.com/questions/862570/relaycommand-in-wpf[^]


Hope it helps


这篇关于WPF ListBox itemTemplate和Button按下事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆