c# - 当 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”,我发现这个如何在打开窗口时将数据模板化的文本框聚焦在窗口中 ItemsControl 的第一个元素中?(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 事件上调用它,但这是一样的。
我什么时候可以打电话?还是我应该以其他方式做?
解决方案
推荐阅读
- rust - 做 unwrap_or_return 的任何方式都可以提前返回
- python - 正则表达式:如何匹配某些字符所包含的内容?
- c++ - cout'ed 时字符串不会出现在屏幕上
- haskell - 如何将 R 转换为 C?
- reactjs - react navigation v4 - 同一堆栈的不同过渡动画| 反应原生
- java - 在谷歌地图上搜索
- css - 如何对齐反应引导导航栏项目?
- .net-core - 如何管理 SignalR 核心中的组?(加入/离开所有人)
- reactjs - React / React-Native 在哪里存储带有钩子的动态引用
- reactjs - 如何在 React JS 中制作水平滚动条,例如 Google 的那种?