簡體   English   中英

C# UWP 在 ListView 的 ItemTemplate 中獲取項目

[英]C# UWP Get Items in ListView's ItemTemplate

我正在嘗試訪問列表視圖中的文本塊和文本框,但無法在 C# 代碼中獲取它們,因為它們位於 ItemTemplate 和 DataTemplate 中。 這是 XAML 代碼的示例:

<ListView x:Name="VehicleList" HorizontalAlignment="Center" Height="120" Margin="0" VerticalAlignment="Center" Width="1119" Background="{ThemeResource CheckBoxDisabledForegroundThemeBrush}" SelectionChanged="VehicleList_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="VehicleGrid" Height="52" Width="1117" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20,0,0,0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="318*"/>
                        <ColumnDefinition Width="425*"/>
                        <ColumnDefinition Width="366*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock x:Name="Year" Grid.Column="0" TextWrapping="Wrap" Text="{Binding Year}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="321" FontSize="26.667"/>
                    <TextBlock x:Name="Make" Grid.Column="1" TextWrapping="Wrap" Text="{Binding Make}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="425" FontSize="26.667" />
                    <TextBlock x:Name="Model" Grid.Column="2" TextWrapping="Wrap" Text="{Binding Model}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="366" FontSize="26.667"/>
                    <TextBox x:Name="AddYear" Grid.Column="0" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="321" FontSize="26.667" Visibility="Collapsed"/>
                    <TextBox x:Name="AddMake" Grid.Column="1" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="425" FontSize="26.667" Visibility="Collapsed"/>
                    <TextBox x:Name="AddModel" Grid.Column="2" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="366" FontSize="26.667" Visibility="Collapsed"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

無論如何要獲取DataTemplate中的項目?

您的問題是所有XAML風格都通用的,在WPF和Silverlight中都是相同的。 問題是您的DataTemplate。 請記住,XAML將為列表中的每個項目注入一次DataTemplate的內容。 這意味着您的名稱只能存在於DataTemplate實例的范圍內。

如果您的模板后面有代碼,則可以通過創建UserControl來做得更好。 參見以下示例:

<!-- most boiler plate code skipped -->
<UserControl x:Class="MyProject.VehicleListItem">
    <Grid x:Name="VehicleGrid" Height="52" Width="1117" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20,0,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="318*"/>
            <ColumnDefinition Width="425*"/>
            <ColumnDefinition Width="366*"/>
        </Grid.ColumnDefinitions>
        <TextBlock x:Name="Year" Grid.Column="0" TextWrapping="Wrap" Text="{Binding Year}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="321" FontSize="26.667"/>
        <TextBlock x:Name="Make" Grid.Column="1" TextWrapping="Wrap" Text="{Binding Make}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="425" FontSize="26.667" />
        <TextBlock x:Name="Model" Grid.Column="2" TextWrapping="Wrap" Text="{Binding Model}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="366" FontSize="26.667"/>
        <TextBox x:Name="AddYear" Grid.Column="0" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="321" FontSize="26.667" Visibility="Collapsed"/>
        <TextBox x:Name="AddMake" Grid.Column="1" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="425" FontSize="26.667" Visibility="Collapsed"/>
        <TextBox x:Name="AddModel" Grid.Column="2" TextWrapping="Wrap" Text="TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Height="52" Grid.ColumnSpan="1" TextAlignment="Center" Width="366" FontSize="26.667" Visibility="Collapsed"/>
    </Grid>
</UserControl>

這樣一來,您就可以從可實例化的UserControl進行所需的所有操作,在其背后添加自己的代碼,等等。您可以完全按照所需的方式工作,然后在列表中按需引用它,如下所示:

<ListView x:Name="VehicleList" HorizontalAlignment="Center" Height="120" Margin="0" VerticalAlignment="Center" Width="1119" Background="{ThemeResource CheckBoxDisabledForegroundThemeBrush}" SelectionChanged="VehicleList_SelectionChanged">
    <ListView.ItemTemplate>
        <DataTemplate>
            <myProject:VehicleListItem/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ListView將為您的用戶控件的DataContext分配一個載具項目,並且一切將按您設計的目的工作。

有一種方法可以使代碼隱藏在可視樹中,但是它非常復雜。 本質上,您需要使用ListView.ItemContainerGenerator並調用ContainerFromItem(dataItem)ref ),然后從中獲得可視化樹。 這不僅是一項艱巨的工作,而且不能保證所有API都可以從WPF到UWP或SilverLight進行訪問。 最干凈的解決方案是將代碼分成獨立的部分。


另一個解決方案可能比我建議的要干凈的多,這是利用您的綁定對象。 ListView.SelectedItem返回綁定到DataTemplate對象。 只需從該對象獲取值即可。 如果您的ViewModel包含AddYearAddMakeAddModel屬性,則由於您根本不用XAML,因此它使許多工作變得更容易。

如果可以的話,只需單擊一下按鈕即可; 您可以使用CommandParameter或遍歷VisualTree,如以下兩個鏈接所示:

如何從ListViewItem的DataTemplate中的TextBox獲取文本

如何從XAML的文本框中獲取值?

用戶控件

聽起來您想要的是UserControl

項目添加用戶控件

這應該很容易,因為您已經具有XAML設計。 后面的代碼如下所示:

public class VehicleView : UserControl
{
    // Year
    public static readonly DependencyProperty YearProperty =
        DependencyProperty.Register("Year", typeof(int), typeof(VehicleView),
            new PropertyMetadata());

    public int Year
    {
        get { return (int)GetValue(YearProperty); }
        set { SetValue(YearProperty, value); }
    }

    // Make
    public static readonly DependencyProperty MakeProperty =
        DependencyProperty.Register("Make", typeof(string), typeof(VehicleView),
            new PropertyMetadata("None"));

    public string Make
    {
        get { return (string)GetValue(MakeProperty); }
        set { SetValue(MakeProperty, value); }
    }

    // Model
    public static readonly DependencyProperty ModelProperty =
        DependencyProperty.Register("Model", typeof(string), typeof(VehicleView),
            new PropertyMetadata("None"));

    public string Model
    {
        get { return (string)GetValue(ModelProperty); }
        set { SetValue(ModelProperty, value); }
    }

    public VehicleView()
    {
        InitializeComponent();
    }
}

綁定單詞的方式相同。 只需使用x:Name命名UserControl即可。 就像是:

<UserControl x:Name="vehicleview"
             x:Class="MyProjectClass"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d">

    <Grid>
        <!-- Here's where your ListView goes. -->
        <TextBox Text="{Binding ElementName=vehicleview, Path=Model}"/>
    <Grid>

</UserControl>

如我所見,您已經使用綁定。

VehicleList_SelectionChanged您可以執行以下操作

List<YouClass-Model> selectedItems = VehicleList.SelectedItems.Cast<YouClass-Model>().ToList();

或者如果您使用ItemClicked EventHandler

 YouClass-Model itemClicked = (YouClass-Model)e.ClickedItem)

這樣,您可以加載綁定的數據。 ex itemClicked.Model

還要確保您正確綁定了數據

數據綁定概述

INotifyPropertyChanged.PropertyChanged

要從索引或數據獲取UI控件,請使用listView.ContainerFromIndexlistView.ContainerFromItem 這是UWP中公認的方式。

試試這個代碼:

private void myListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
    {
        ListItemData data = args.Item as ListItemData;
        ListViewItem a = args.ItemContainer as ListViewItem;
        var b = a.ContentTemplateRoot as Grid;  
        var txtBlock =b.FindName("txtTitle") as TextBlock;
        txtBlock.Text = data.Title;
        TextRange textRange = new TextRange()
        {
            StartIndex = 1,
            Length = 3
        };
        TextHighlighter highlighter = new TextHighlighter()
        {
            Background = new SolidColorBrush(Colors.Yellow),
            Ranges = { textRange }
        };
        txtBlock.TextHighlighters.Add(highlighter);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM