Установите Фокус на текстовое поле под списком DataTemplate - PullRequest
1 голос
/ 27 ноября 2011

Я новичок в WPF и XAML.Я сделал Listbox с элементами текстового поля и хотел, чтобы текстовое поле выбранного элемента было сфокусировано при каждом выборе этого элемента.Мой друг предложил мне использовать ItemContainer, и я попытался использовать триггер со свойством setter TextBox.IsFocused, но я продолжал получать ошибку IsFocused, которая не может быть установлена.

Что пошло не так?Ниже мой код:

Обновлен XAML:

<DataTemplate x:Key="Template">
            <Grid Margin="3">
                <Border BorderThickness="2" BorderBrush="Black"
                          Background="{Binding RelativeSource=
                          {
                             RelativeSource 
                             Mode=FindAncestor, 
                             AncestorType={x:Type ListBoxItem}
                          }, 
                          Path=Background
                         }" CornerRadius="4">
                    <StackPanel HorizontalAlignment="Stretch" Margin="3" >
                        <StackPanel.Style>
                            <Style>
                                <Setter Property="TextBlock.Foreground" Value="Black"></Setter>
                            </Style>
                        </StackPanel.Style>
                        <TextBlock Foreground="White" FontSize="18" TextWrapping="Wrap" Text="{Binding Path=BenefitDesc}"></TextBlock>
                        <Grid Margin="3" HorizontalAlignment="Stretch">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="1*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <TextBlock Foreground="White" Margin="3" FontSize="16" TextWrapping="Wrap">Price:</TextBlock>
                            <TextBox x:Name="txtUpdate" FontSize="16" Grid.Column="1" TextWrapping="Wrap" Text="{Binding Path=Price}" Margin="3">
                            </TextBox>
                        </Grid>
                    </StackPanel>
                </Border>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox x:Name="lsItem" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                 HorizontalContentAlignment="Stretch" Background="#FF2CB7D2" SelectionChanged="lsBenPriceEditor_SelectionChanged"
                 ItemTemplate="{StaticResource Template}">
            <ListBox.ItemContainerStyle>
                <Style>
                    <Setter Property="Control.Padding" Value="0"></Setter>
                    <Style.Triggers>
                        <Trigger Property="ListBoxItem.IsSelected" Value="True">
                            <Setter Property="ListBoxItem.Background" Value="DarkRed" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>

1 Ответ

2 голосов
/ 27 ноября 2011

Вы можете перехватить событие SelectionChanged в своем коде позади для вашего Listbox, и там вы можете перебрать визуального потомка вашего SelectedItem, чтобы найти ваш textBox, и просто вызвать textBox.Focus(), чтобы поместить фокус на текстовое поле.

Код

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   ListBox lb = sender as ListBox;
   ListBoxItem lbi = (ListBoxItem)lb.ItemContainerGenerator.ContainerFromItem(lb.SelectedItem);
   TextBox textBox = GetVisualChild<TextBox>(lbi);
   if (textBox != null)
      textBox.Focus();
}

private T GetVisualChild<T>(Visual parent) where T : Visual
{
   T child = default(T);
   int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
   for (int i = 0; i < numVisuals; i++)
   {
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
      child = v as T;
      if (child == null)
      {
         child = GetVisualChild<T>(v);
      }
      if (child != null)
      {
         break;
      }
   }
   return child;
}

GetVisualChild - это универсальный метод, который можно использовать для циклического прохода по VisualChildren для переданного UIControl(ListBoxItem in your case) и возврата требуемого элемента T(TextBox in your case) из списка VisualChildren.

Кроме того, свойство IsFocused, предоставляемое UIElement, является свойством только для получения.

public bool IsFocused { get; }

Вот почему вы получаете эту ошибку ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...