views:

201

answers:

2

I have a simple ListBox.ItemTemplate containing a Label and a TextBox bound to a CSLA Bindable List. When I select the textbox the CurrentItem does not change, It only changes if I select the label. I have IsSynchronizedWithCurrentItem='True'.

<ListBox x:Name="ItemsDataGrid"
                 ItemsSource="{Binding Source={StaticResource AuditItems},Path=Items}"
                 IsSynchronizedWithCurrentItem="True">
         <ListBox.ItemTemplate>
             <DataTemplate>
                 <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="200"></ColumnDefinition>
                            <ColumnDefinition Width="100"></ColumnDefinition>
                        </Grid.ColumnDefinitions>

                        <Label Grid.Column="0" 
                               Content="{Binding Path=TypeRef}" />

                        <TextBox x:Name="TextBoxQty" 
                                 Grid.Column="1" 
                                 Text="{Binding Path=TaliQty}"/>                                                                                                                                            

                    </Grid>
                </DataTemplate>                                
            </ListBox.ItemTemplate>                        
        </ListBox>
A: 

This is happening because the TextBox is handling the MouseDown event. As it is set to bubble up it will not reach the containing ListBoxItem. The simplest way to fix this would be to just handle the selection of the ListBoxItems in the PreviewMouseDown, which will occur and tunnel down before the actual MouseDown event bubbles up.

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <EventSetter Event="PreviewMouseDown"
                     Handler="ListBoxItem_PreviewMouseDown" />
    </Style>
</ListBox.ItemContainerStyle>

And in the Code behind for the xaml file:

private void ListBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var item = (sender as ListBoxItem);
    if (item != null)
        item.IsSelected = true;
}
rmoore
Perfect thank you, forgot all about the bubble up!
+2  A: 

Try adding this to your ListBox. It selects the item any time any contained element (like TextBox) gets keyboard focus. A similar method could also be used with just a simple setter in the Trigger but that tends to interfere with the CurrentItem setting on the ICollectionView:

         <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Style.Triggers>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="SetSelected">
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected">
                                        <DiscreteBooleanKeyFrame KeyTime="0:00" Value="True" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="SetSelected"/>
                        </Trigger.ExitActions>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
John Bowen
Excellent, and well thought out!