#c# #.net #listview #uwp
#c# #.net #listview #uwp
Вопрос:
У меня есть ListView
поддержка an ObservableCollection
. Пользователь может добавить новую строку, где в коде я добавляю новый объект в коллекцию : array.Add(obj)
.
Теперь я хотел бы сделать, это сфокусироваться на a TextBox
в новой строке. Проблема в том, что я считаю, что мне нужно подождать, пока не будет создан пользовательский интерфейс, и я не знаю события, которое сообщит мне, когда новая строка будет готова.
Я пытался получить новый контейнер и ссылку на TextBox
in ListView_SelectionChanged
, но я получал нулевые возвращаемые значения в новой строке.
Я пробовал использовать ListViewItem.Loaded
, но, похоже, это не вызывается для переработанных строк.
Я также пытался ListViewItem.GotFocus
, но это не было вызвано после добавления новой строки в коде.
Если бы я знал, когда элементы управления на ListViewItem
были готовы, я мог бы затем найти TextBox
и установить его фокус.
Возможно, я делаю это сложнее, чем нужно, но я не уверен, как поступить.
Ответ №1:
Я отвечаю на свой собственный вопрос. Ниже то, что я придумал.
Xaml: (добавьте два обработчика событий в сетку)
<DataTemplate x:Key="MyTemplate" x:DataType="model:Card">
<Grid GotFocus="ListViewGrid_GotFocus" DataContextChanged="ListViewGrid_DataContextChanged">
<StackPanel Orientation="Horizontal">
<TextBox Name="Text1" Text="{x:Bind Text1}" />
</StackPanel>
</Grid>
</DataTemplate>
Код:
MyListView.Items.VectorChanged = ListViewItems_VectorChanged; // in constructor
private void AddRow_Click(object sender, RoutedEventArgs e) {
card = ....
_newRowCard = card;
_array.Add(card);
}
private void ListViewItems_VectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs @event) {
// If new row added, at this point we can safely select and scroll to new item
if (_newRowCard != null) {
MyListView.SelectedIndex = MyListView.Items.Count - 1; // select row
MyListView.ScrollIntoView(MyListView.Items[MyListView.Items.Count - 1]); // scroll to bottom; this will make sure new row is visible and that DataContextChanged is called
}
}
private void ListViewGrid_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) {
// If new row added, at this point the UI is created and we can set focus to text box
if (_newRowCard != null) {
Grid grid = (Grid)sender;
Card card = (Card)grid.DataContext; // might be null
if (card == _newRowCard) {
TextBox textBox = FindControl<TextBox>(grid, typeof(TextBox), "Text1");
if (textBox != null) textBox.Focus(FocusState.Programmatic);
_newRowCard = null;
}
}
}
private void ListViewGrid_GotFocus(object sender, RoutedEventArgs e) {
// If user clicks on a control in the row, select entire row
MyListView.SelectedItem = (sender as Grid).DataContext;
}
public static T FindControl<T>(UIElement parent, Type targetType, string ControlName) where T : FrameworkElement {
if (parent == null) return null;
if (parent.GetType() == targetType amp;amp; ((T)parent).Name == ControlName) return (T)parent;
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i ) {
UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
T result = FindControl<T>(child, targetType, ControlName);
if (result != null) return resu<
}
return null;
}
Комментарии:
1. Привет, Притхви. Я не использовал UWP более 2 лет, поэтому я действительно не знаю. Извините.