Nestor
Nestor

Reputation: 8384

WPF ListBoxItem IsSelected property selects only for an instant

I have a ListBoxItem template with a TextBox element within. When the user clicks the TextBox, I should make the ListBoxItem as the SelectedItem of the ListBox.

<ListBox.ItemTemplate>
        <DataTemplate>
          <DockPanel Margin="4,0,4,0">
            <TextBlock Text="{Binding Path=Value1, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                        ToolTip="{Binding Path=Hint, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                        VerticalAlignment="Center" />
            <TextBox x:Name="TextField"                              
                          Margin="2,0,0,0"
                          Width="{Binding Path=ActWidth, Mode=OneWay}"
                          Visibility="{Binding Path=VisibleAct, Mode=OneWay}"
                          />
        </DockPanel>
        </DataTemplate>
</ListBox.ItemTemplate>

I have the following Trigger to make the selection:

<ListBox.Resources>
    <Style TargetType="ListBoxItem">
      <Style.Triggers>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
          <Setter Property="IsSelected" Value="True" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </ListBox.Resources>

Unfortunately, it works only for an instant, when I change the focus, the selection disappears. If I remove the trigger, it works normally but selecting the TextBox does not trigger the selection.

What should I do to make the selection permanent?

Upvotes: 0

Views: 607

Answers (2)

sTrenat
sTrenat

Reputation: 1049

Your sample doesn't work because, if the trigger is false, your ListBoxItem is getting the value as it had before triggering. Your ListBoxItem is like 'ehmm, what I was..'.

So you have to set its SelectedValue by adding a default setter that binds its IsSelected state:

<Style TargetType="ListBoxItem">
    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode="OneWay", RelativeSource={RelativeSource Self}}" />
    <Style.Triggers>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="IsSelected" Value="True" />
        </Trigger>
    </Style.Triggers>
</Style>

Setting default setter for IsSelected as OneWay binding to itself will do the job. It will set IsSelected as it was, when the trigger is false.

Upvotes: 1

mm8
mm8

Reputation: 169190

You could write some code to set the SelectedItem property of the ListBox. You could handle the GotKeyboardFocus event for the TextBox:

<ListBox x:Name="lb2">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <DockPanel Margin="4,0,4,0">
                <TextBlock Text="{Binding Path=Value1, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                        ToolTip="{Binding Path=Hint, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                        VerticalAlignment="Center" />
                <TextBox x:Name="TextField"                              
                          Margin="2,0,0,0"
                          Width="{Binding Path=ActWidth, Mode=OneWay}"
                          Visibility="{Binding Path=VisibleAct, Mode=OneWay}"
                          GotKeyboardFocus="TextField_GotKeyboardFocus"
                          />
            </DockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

private void TextField_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    TextBox textBox = sender as TextBox;
    lb2.SelectedItem = textBox.DataContext;
}

Upvotes: 0

Related Questions