none
Programmatically adding buttons to a WPF Window

    Question

  • Hi,

    I've run into a bit of a stumbling block on the best way to go about achieving something with WPF, and thought this might be the best place to post a question.

    What I need to do is retrieve records from a database (an ID and text field), and present them to the User in the form of Buttons on screen - the Content of the button being the text field, when the User clicks the button I need to do something with the ID.

    I used some ideas I saw in Martin Grayson's Introduction to Blend series on Channel9 (part 3 - http://channel9.msdn.com/Showpost.aspx?postid=286767), and created an XML file with the returned records from the Database. With this XML file to be used as an XML Data Source, it's filling up a ListBox with items containing a hidden Label with the ID field, and a Button with the Text. My first problem with this is that I'm not sure how to get to the button's click event! Also, I need to have the buttons spaced out a bit (it's a touchscreen interface), and would prefer to have the label collapsed rather than hidden, but can't figure a way to space the buttons out and also NOT highlight the selected listbox item in blue (I can see how to set the blue colour to a different one but not to remove it).

    I think there could be a better way to tackle the problem, but being brand-new to WPF I'm not sure exactly how. As I said, what I need to do is programmatically add buttons to the screen, and the react to a button being clicked. Any suggestions?

    Thanks
    Neal

    Monday, April 30, 2007 10:00 AM

Answers

  • <ListBox Name="list1" Button.Click="btn_Click">

    ...

    </ListBox>

     

    in codebehind

    void btn_Click(object sender, RoutedEventArgs e)

    {

          Button b = e.OriginalSource as Button;

    }

    Monday, April 30, 2007 1:11 PM
  • I'd like to recommend a slightly diff. approach: Use commands.

    1. Register yourself a custom command
    2. In your template, assign the command to the Button's Command property
    3. Again in your template, bind the ID to the CommandArgument property
    4. Handle the command

    When the button is clicked, it will do it's business and raise the RoutedCommand. You can handle it at the Window level and you'll get the ID of the button from the Argument property of the ExecutedRoutedEventArgs.

     

    The added benefit with this approach is that, no matter how much the designer changes the UI (you know they're not gonna want just buttons at some point! ), all they have to do is raise that command and your code doesn't ever have to change.

     

    Cheers,
    Drew

    Monday, April 30, 2007 2:01 PM

All replies

  • I think it might be easier to use a listbox and bind the data. create a listboxitem template with a button in it, bind the text to the content of the button and id to the Tag of the button. Add a Button.click handler on the listbox to handle the button click event.
    Monday, April 30, 2007 12:26 PM
  • Thank lee - I'll look into it
    Monday, April 30, 2007 12:30 PM
  •  lee d wrote:
    Add a Button.click handler on the listbox to handle the button click event.

    Hi Lee - could you give me a bit more detail on how I'd achieve this part?

    Monday, April 30, 2007 1:00 PM
  • <ListBox Button.Click="OnAnyButtonInTheListBoxClick" ... />

     

    Since the Click event is routed, it will be raised for the ListBox which contains each Button.  Putting a common handler on the ListBox enables you to have one place where all Button clicks go to.  See here for more info: http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!280.entry

    Monday, April 30, 2007 1:08 PM
  • <ListBox Name="list1" Button.Click="btn_Click">

    ...

    </ListBox>

     

    in codebehind

    void btn_Click(object sender, RoutedEventArgs e)

    {

          Button b = e.OriginalSource as Button;

    }

    Monday, April 30, 2007 1:11 PM
  • Thanks for both the replies on this, I didn't realise you could use the Button.Click at the overall ListBox level. I'm new to WPF, I'm reading Adam Nathan's 'WPF Unleashed' on your glowing recommendation Josh but am not that far into it.

     

    Do you have any suggestions as to the best way to go about what I need to do? I feel that the ListBox mightn't be the best way...

     

    I need to programmatically add buttons to a screen - it's a touchscreen interface so they will have to be spaced out a bit from each other - any suggestions?

    Monday, April 30, 2007 1:38 PM
  • Neal,

     

    You might want to check out this article on how to get a listbox to layout in an entirely different way:

    http://www.codeproject.com/useritems/CustomListBoxLayoutInWPF.asp

     

    WPF lets you think about things like listboxes in entirely new ways.  This article is a good example of a basic twist.

     

    Cheers,

    James

    Monday, April 30, 2007 1:55 PM
  • you could just add appropriate margin to the buttons, they will be spaced.
    Monday, April 30, 2007 1:57 PM
  • I'd like to recommend a slightly diff. approach: Use commands.

    1. Register yourself a custom command
    2. In your template, assign the command to the Button's Command property
    3. Again in your template, bind the ID to the CommandArgument property
    4. Handle the command

    When the button is clicked, it will do it's business and raise the RoutedCommand. You can handle it at the Window level and you'll get the ID of the button from the Argument property of the ExecutedRoutedEventArgs.

     

    The added benefit with this approach is that, no matter how much the designer changes the UI (you know they're not gonna want just buttons at some point! ), all they have to do is raise that command and your code doesn't ever have to change.

     

    Cheers,
    Drew

    Monday, April 30, 2007 2:01 PM
  • I would make a listbox and make the item template be a button, then have the button Content bind to your content property of your data and the Command property bind to a Command property on your data object. (but as someone said, a giant scrollable list of buttons would look kindof silly and not work so well because the user would be clicking on the list and hitting the buttons when they didn't want to. I would make 1 button that binds to the selected item's command.
    Monday, April 30, 2007 3:05 PM