首页 > 解决方案 > 当 ItemsSource 更改时,聚焦 itemsControl 模板的第一个文本框

问题描述

我正在使用 MVVM 模式在 C#/WPF 中开发应用程序。我有一个显示一些支持的屏幕。每个支撑都有一些空间的集合。用户必须能够输入一些关于空间的信息。

我的视图上有一个 GlobalViewModel 作为数据上下文。它包含一个 ObservableCollection 的 SupportViewModels 和一个当前的 SupportViewModel,这些对象被绑定到一个 DataGrid。下面我使用带有 dataTemplate 的 ItemsControl 来显示空格。ItemsControl.ItemsSource 绑定到 CurrentSupport.Spaces(= SpaceViewModels 的 ObservableCollection)。

如果我简化我的观点,会是这样的

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <telerik:RadGridView Grid.Row="0"
                         x:Name="supportGrid" 
                         CanUserDeleteRows="False" 
                         CanUserInsertRows="False" 
                         ItemsSource="{Binding Supports}" 
                         SelectedItem="{Binding CurrentSupport}" 
                         AutoGenerateColumns="False" >
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn Header="Code" DataMemberBinding="{Binding Code}"/>
            <telerik:GridViewDataColumn Header="State" DataMemberBinding="{Binding State, Converter={StaticResource EnumValueToTextConverter}}"/>
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
    <Grid Grid.Row="1" >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <telerik:Label Grid.Column="0" Content="Code" />
        <telerik:RadWatermarkTextBox Grid.Column="1" Text="{Binding CurrentSupport.Code, Mode=OneWay}" IsReadOnly="True" />
    </Grid>
    <ItemsControl Grid.Row="2"
                  x:Name="spacesItems" 
                  ItemsSource="{Binding CurrentSupport.Spaces}" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <telerik:GroupBox Grid.ColumnSpan="2" 
                                      HorizontalContentAlignment="Center" 
                                      VerticalContentAlignment="Center" 
                                      Header="{Binding Code, Mode=OneWay}"
                                      >
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <telerik:Label Grid.Column="0" Content="Ref." />
                            <telerik:RadMaskedTextInput x:Name="findSearchBox" 
                                                            Grid.Column="1"
                                                            Mask="" 
                                                            HorizontalAlignment="Stretch"
                                                            SelectionOnFocus="SelectAll">
                            </telerik:RadMaskedTextInput>
                            <telerik:RadButton Grid.Column="2"
                                                   Command="{Binding FindCommand}"
                                                   CommandParameter="{Binding Text, ElementName=findSearchBox}" 
                                                   Content="Search" />

                            <!-- *** Some other fields *** -->

                        </Grid>
                    </telerik:GroupBox>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

我希望在更改当前支持时(由用户或通过代码),然后选择第一个空间的第一个文本框(在 spacesItems DataTemplate 中定义)

要选择第一个空间上的“findSearchBox”,我发现这个如何在打开窗口时将数据模板化的文本框聚焦在窗口中 I​​temsControl 的第一个元素中?(C#,WPF)

private void SetFocusOnSearchBox()
{
    if (!spacesItems.HasItems)
        return;

    DependencyObject cp = spacesItems.ItemContainerGenerator.ContainerFromIndex(index: 0);
    RadMaskedTextInput tb = FindVisualChild<RadMaskedTextInput>(cp);
    if (tb != null)
    {
        FocusManager.SetFocusedElement(spacesItems, tb);
    }
}

如果我在单击按钮时调用该方法,则效果很好,但是当我在 DataGrid 的 SelectionChanged 事件上调用该方法时,它不起作用,因为spacesItems.ItemContainerGenerator.ContainerFromIndex(0)此时还没有任何子级。我也尝试在 CurrentSupport propertyChanged 事件上调用它,但这是一样的。

我什么时候可以打电话?还是我应该以其他方式做?

标签: c#wpfxamlitemscontrol

解决方案


推荐阅读