Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

wpf - Select ListBoxItem if TextBox in ItemTemplate gets focus

I have added a DataTemplate to a ListBox class to bind my collection to:

<ListBox x:Name="lstEmails" Height="259" Margin="12,0,12,41" Width="276"
         SelectionChanged="lstEmails_SelectionChanged">
    <ListBox.ItemTemplate> 
        <DataTemplate> 
            <StackPanel Orientation="Horizontal"> 
                <Label Visibility="Hidden" Content="{Binding ID}"></Label> 
                <TextBox Width="200"  Text="{Binding EmailAddress}"></TextBox> 
            </StackPanel> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

This does exactly what I want it to do. Although when I click on the TextBox, the ListBox does not automatically set the associated ListItem as Selected. I could do this in code, but I would prefer to use this as a component (no surprises there then).

Any ideas on how to achieve this?


That doesn't seem to work, it won't let me click on anything. Have I missed something. Here is my new XAML.

<UserControl.Resources> 
    <!--<TextBox x:Key="TB" x:Name="TextBoxInsideListBoxItemTemplate"> 
        <TextBox.Style>--> 
            <Style TargetType="{x:Type TextBox}"> 
                <Setter Property="IsHitTestVisible" Value="False" /> 
                <Style.Triggers> 
                    <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" 
                                                     Value="True"> 
                        <Setter Property="IsHitTestVisible" Value="True" /> 
                    </DataTrigger> 
                </Style.Triggers> 
            </Style> 
        <!--</TextBox.Style> 
    </TextBox>--> 
</UserControl.Resources> 
<Grid> 
    <ListBox x:Name="lstEmails" Height="259" Margin="12,0,12,41" Width="276" SelectionChanged="lstEmails_SelectionChanged">
        <ListBox.ItemTemplate> 
            <DataTemplate> 
                <StackPanel Orientation="Horizontal"> 
                    <!--<Label Visibility="Hidden" Content="{Binding ID}"></Label>--> 
                    <TextBox Width="220" Text="{Binding EmailAddress}" > 
                    </TextBox> 
                    <!--<TextBox Width="220" Text="{Binding EmailAddress}" GotFocus="TextBox_GotFocus"></TextBox>-->
                </StackPanel> 
            </DataTemplate> 
        </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Width="20" Margin="12,0,0,12" Name="btnAdd" VerticalAlignment="Bottom" Click="btnAdd_Click" Height="23" HorizontalAlignment="Left">+</Button>
    <Button Width="20" HorizontalAlignment="Left" Margin="30,0,0,12" Name="btnRemove" VerticalAlignment="Bottom" Click="btnRemove_Click" Height="23">-</Button>
    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,12,12" Name="btnApply" VerticalAlignment="Bottom" Width="49" Click="btnApply_Click">Apply</Button>
</Grid>

I think the click twice bit is good functionality.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can trigger on the property IsKeyboardFocusWithin in the ItemContainerStyle and set IsSelected to true.

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}}" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ListBoxItem.IsSelected)">
                                <DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
                            </BooleanAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>

You could also use a Setter instead of a single frame animation but then the selection will be lost again once the focus leaves the ListBox:

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}}" Value="True">
                <Setter Property="IsSelected" Value="True"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...