【问题标题】:ListView - Set focus on a control in a new row (UWP)ListView - 将焦点设置在新行中的控件上 (UWP)
【发布时间】:2017-02-24 02:52:15
【问题描述】:

我有一个ListView 支持一个ObservableCollection。用户可以添加一个新行,在代码中我将一个新对象添加到集合中:array.Add(obj)

现在我想做的是关注新行中的TextBox。问题是我认为我需要等到 UI 创建完成,而且我不知道有什么事件可以让我知道新行何时准备就绪。

我尝试在ListView_SelectionChanged 中获取新容器和对TextBox 的引用,但我在新行上得到了空返回值。

我尝试过使用ListViewItem.Loaded,但似乎没有为回收行调用。

我也试过ListViewItem.GotFocus,但在代码中添加新行后没有调用它。

如果我知道ListViewItem 上的控件何时准备就绪,我就可以找到TextBox 并设置它的焦点。

也许我让这件事变得比需要的更难,但我不知道如何继续。

【问题讨论】:

    标签: c# .net listview uwp


    【解决方案1】:

    我正在回答我自己的问题。以下是我想出的。

    Xaml:(向 Grid 添加两个事件处理程序)

    <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 && ((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 result;
        }
        return null;
    }
    

    【讨论】:

    • 嗨普里特维。我已经 2 年多没用过 UWP 了,所以我真的不知道。对不起。
    猜你喜欢
    • 2011-03-21
    • 1970-01-01
    • 2010-09-14
    • 2011-10-26
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多