7

I'm using an ItemsControl to display a list of databound items, for each the core of the DataTemplate is a Grid upon which I've placed all the bound controls.

I would like to be able to click on the entire area for each item in the list. But I cannot figure out how to make the area clickable.

Any suggestions of how to make an entire grid area clickable would be great.

Adam Haile
  • 30,705
  • 58
  • 191
  • 286
  • what exactly causes this problem? i'm trying to understand why this happens. Shouldn't a click on a the item result in a preview mouse event tunneling down the tree to the treeviewitem? or is treeviewitem not the focus of the mouse event? I thought that mouse events were raised based on hit testing that would get the innermost element on the visual tree (which I assume would be the treeviewitem) and then make that the target of the event – James Joshua Street Aug 16 '13 at 00:52

2 Answers2

16

To make something clickable you can usually wrap it in a Button, if it should be "invisible" you can change the template:

<Button.Template>
    <ControlTemplate TargetType="{x:Type Button}">
        <ContentPresenter />
    </ControlTemplate>
</Button.Template>
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 2
    +1: For the life of me, I cannot believe that in a four years I have been writing in XAML I have never thought of doing that. – fatty Aug 28 '11 at 03:17
  • @fatty: Oh wow; i for one cannot believe that most controls have all sorts of mouse events but not a simple click, maybe they thought that the button would then be useless as everything can be styled like one anyway ([here'd be a related question of mine](http://stackoverflow.com/questions/4830164/what-is-the-best-way-to-simulate-a-click-with-mouseup-mousedown-events-or-other)) – H.B. Aug 28 '11 at 03:22
  • Nice one, it's crazy to think how stuck in your history you can get when you do the same thing over and over. Can't wait until I can get a decent 'net connection from under this rock I seem to be living under. – fatty Aug 28 '11 at 03:30
4

You can use the AttachedCommandBehavior classes from C# Disciples to achieve this.

Define a command in the ViewModel, and then on the Grid object use the ACB AttachedProperties to bind the MouseLeftButtonUp event to the command.

Some code to get you started:

        <Grid Name="grid" Height="30" ForceCursor="True" Cursor="Hand">
            <acb:CommandBehaviorCollection.Behaviors>
                <acb:BehaviorBinding Event="MouseLeftButtonUp" Command="{Binding Path=DataContext.EditEventCommand, RelativeSource={RelativeSource AncestorType={x:Type self:Dashboard}}}" CommandParameter="{Binding}" />
            </acb:CommandBehaviorCollection.Behaviors>
        </Grid>

Edit for non-MVVM solution.

The above code snippet will still work when you have not designed your application following the MVVM guide-lines as you are essentially just binding to a command in the code-behind.

However, if you don't want to go to the trouble of defining commands, you can simply specify an event to hook to, like so:

<Grid MouseLeftButtonUp="Grid_MouseLeftButtonUp"> in the XAML file.

and in the code-behind:

    private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    }        
fatty
  • 2,453
  • 2
  • 25
  • 24
  • Does that still work if I'm not using MVVM? (Honestly don't know how as of yet...) – Adam Haile Aug 28 '11 at 01:41
  • Yes, this will still work when not using MVVM - but I have updated my answer with some additional code. Note that this will trigger on MouseUp, not Click. If you want to trigger on click, you will need to capture both MouseDown and Up events, start a timer to measure the time taken between each, and then trigger accordingly. – fatty Aug 28 '11 at 01:50