将Focus设置为List DataTemplate下的文本框

时间:2011-11-27 06:37:25

标签: .net wpf xaml

我是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 个答案:

答案 0 :(得分:2)

您可以在Listbox的代码中挂钩SelectionChanged事件,然后您可以遍历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)并从VisualChildren列表中返回所需的元素T(TextBox in your case)

此外,UIElement公开的IsFocused属性是get get属性。

public bool IsFocused { get; }

这就是你收到这个错误的原因..