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! 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 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.
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;
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
  • Read the question carefully.
  • Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  • If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  • Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question. Let's work to help developers, not make them feel stupid.
  •