简体   繁体   中英

Access a Named Control Inside a XAML DataTemplate

I managed to access control in the datatemplate of a GridViewItem, the following code:

private void btnChangePhoneNumber_Click(object sender, RoutedEventArgs e)
    {
        GridCell.SelectedItem = GridCell.Items[3];
        var container = GridCell.ContainerFromIndex(3);
        var _children = AllChildren(container);
        var _control = _children.First(c => c.Name == "PhoneNumber");
        _control.text = "123456789";
    }


public List<TextBlock> AllChildrenText(DependencyObject parent)
    {
        var _List = new List<TextBlock> { };
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            var _Child = VisualTreeHelper.GetChild(parent, i);
            if (_Child is TextBlock)
            {
                _List.Add(_Child as TextBlock);
            }

            _List.AddRange(AllChildrenText(_Child));
        }
        return _List;
    }

where the GridCell is a Gridview.

This work.. but..

If I implement GridView with less than 40 items it's all right. Unlike if I implement gridView with 10000 items, the text change that happens with the method: btnChangePhoneNumber_Click , also happens in other items ... and I can not understand the reason since, in the btnChangePhoneNumber_Click method, only one item is chosen.

Thanks in advance. A greeting.

I have tested your code, but I could not reproduce your issue in my side. As far as I'm concerned, It is low performance to render 10000 items in your GridView . And using VisualTreeHelper will bring about worse performance. You could bind the text of TextBlock in the datatemplate with mvvm ViewModel. You just need to modify the view model and the text of TextBlock will be changed. For more please refer to Data binding in depth . And the following is segment code of ViewModel.

MainPageViewModel.cs

public class MainPageViewModel : ViewModelBase
{
    private ObservableCollection<Phone> _items;
    public ObservableCollection<Phone> Items
    {
        get
        {
            return _items;
        }
        set
        {
            _items = value;
            OnPropertyChanged();
        }
    }
    public MainPageViewModel()
    {
        var list = new ObservableCollection<Phone>();
        for (var i = 0; i < 1000; i++)
        {
            list.Add(new Phone { PhoneNumber = "123456" });
        }
        _items = list;
    }

}

MainPage.xaml

<Page.DataContext>
    <local:MainPageViewModel x:Name="ViewModel"/>
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Button Click="btnChangePhoneNumber_Click" Content=" click me"/>
    <GridView x:Name="GridCell" Height="400" ItemsSource="{Binding Items}" >
        <GridView.ItemTemplate>
            <DataTemplate x:DataType="local:Phone">
                <TextBlock Text="{x:Bind PhoneNumber ,Mode=OneWay}"/>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
</StackPanel>

I have upload the code sample to github. Please check!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM