1
votes

I've set up a WPF application which displays a list of views for an application.

The application uses a ListView which is bound to an observable collection of a BrowserItem class (has properties like Name and RelatedViewId etc).

The applicaiton has several hundred views, a few of which have child views - I've handled this by the BrowserItem class having a list of BrowserItem property called 'Children'.

I've set up events so when the user double clicks a view it returns the view name and related element Id from the Browser Class.

I've handled the child views by giving the ListViewItems a TextBlock and a ListView - the listView is then bound to the Children list of the BrowserItem.

This all works nicely:

Capture of application running

The problem I have is that when a child item is clicked both events for child and parent ListItem are fired.

Is there any way the double click event be fired only for the child item, when it is double clicked, and not for its parent container.

Heres the XAML:

<ListView Name="ViewList" ItemsSource="{Binding GroupItems}">

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <EventSetter Event="MouseDoubleClick"
                         Handler="ViewList_MouseDoubleClick" />
        </Style>
        
    </ListView.ItemContainerStyle>

    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                
                <!--This is the child list, it visibility is set to collapsed if the child count = 0-->
                <Expander>
                    <Expander.Style>
                        <Style>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=Children.Count}"
                                             Value="0">
                                    <Setter Property="Expander.Visibility"
                                            Value="Collapsed" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Expander.Style>


                    <ListBox ItemsSource="{Binding Children}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <EventSetter Event="MouseDoubleClick"
                                             Handler="ViewBox_MouseDoubleClickChild" />
                            </Style>
                        </ListBox.ItemContainerStyle>
                    </ListBox>
                    
                </Expander>

                <TextBlock Text="{Binding Name}">
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Active}"
                                             Value="true">
                                    <Setter Property="Background"
                                            Value="YellowGreen" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
                
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>

    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Expander>
                                    <Expander.Header>
                                        <TextBlock Text="{Binding Name}" />
                                    </Expander.Header>
                                    <ItemsPresenter />
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListView.GroupStyle>

</ListView>

The code behind that is called by the events simply gets the object and displays its name:

Event for when a ListItem is clicked:

private void ViewList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{

    ListViewItem picklv = sender as ListViewItem;

    BrowserItem chosen = picklv.Content as BrowserItem;

    MessageBox.Show("Clicked on View: " + chosen.Name + " Element Id: " + chosen.RelatedElement.ToString());

}

Event for when a child item from the View Child list is clicked:

private void ViewBox_MouseDoubleClickChild(object sender, MouseButtonEventArgs e)
{
    ListBoxItem picklb = sender as ListBoxItem;

    BrowserItem pickedsub = picklb.Content as BrowserItem;

    MessageBox.Show("Clicked on Child View: " + pickedsub.Name + " Element Id: " + pickedsub.RelatedElement.ToString());
}
1
The double click events are handled in the ListBox.ItemContainerStyle using a Style tag and EventSetter (as per the first piece of code in the post you referenced). I've updated the question above to include this, and the code behind thats called.Archie456

1 Answers

1
votes

By the child element you have to listen for the PreviewMouseDoubleClick

<EventSetter Event="PreviewMouseDoubleClick" Handler="ViewBox_MouseDoubleClickChild" />

and in the child event handler add e.Handled = true;:

private void ViewBox_MouseDoubleClickChild(object sender, MouseButtonEventArgs e)
{
    var picklb = sender as ListBoxItem;

    var pickedsub = picklb.Content as BrowserItem;

    MessageBox.Show("Clicked on Child View: " + pickedsub.Name + " Element Id: " + pickedsub.RelatedElement.ToString());

    e.Handled = true;
}

This will prevent, that MouseDoubleClick event handler for the parent element will be called.