简体   繁体   中英

wpf - How do I find the ListView row of an element in a GridView cell?

I have a combobox embedded within a grid view cell that is subsequently embedded in ListView object. When the window is loaded, the combobox gets values from my list of container classes and populates the combobox. This works fine, but what I want is to be able to determine the listview index of the combobox whenever the SelectionChanged event is fired.

<ComboBox x:Name="TransFileOpt" ItemsSource="{Binding ComboBoxOptions}" SelectedIndex="{Binding SelectedIndex}" SelectionChanged="ComboBoxSelectionChanged"/>

When I've searched this before, all of the results are directed towards System.Windows.Forms.ListView while I'm working with System.Windows.Controls.ListView, so m_ListView.Rows[index] does not work.

Basically I need a way to get the ListView index or item that contains the combobox that calls ComboBoxSelectionChanged (on firing of the SelectionChanged Event).

The ListView block:

    <ListView Name="m_ListView" ItemsSource="{Binding Tables}" Margin="0,28,0,132" SelectionMode="Extended" SelectedIndex="0" 
              RenderTransformOrigin="0.503,0.468" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
              SelectionChanged="ListView_SelectionChanged">
        <ListView.View>
            <GridView x:Name="m_TableGridView" AllowsColumnReorder="False"  >
                <GridViewColumn Width="50" Header="Loaded">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Loaded}"></CheckBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Width="150" Header="Master File" DisplayMemberBinding ="{Binding MasterFileName}"/>
                <GridViewColumn Width="200" Header ="Translation File" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="TransFileOpt" ItemsSource="{Binding ComboBoxOptions}" 
                                      SelectedIndex="{Binding SelectedIndex}" SelectionChanged="ComboBoxSelectionChanged"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
        <ListView.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text }"></Setter>
            </Style>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.Resources>
    </ListView>

Other info: the project was generated through Visual Studio's wpf editor which defaulted to System.Windows.Controls for classes.

Here is a working example for you:

<Window x:Class="ListViewGridView.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView Margin="10" Name="lvUsers" ItemsSource="{Binding  items}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Items" Width="150">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding containerItems}" SelectionChanged="ComboBox_SelectionChanged">
                                <ComboBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding}"/>
                                    </DataTemplate>
                                </ComboBox.ItemTemplate>
                            </ComboBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

Codebehind:

public partial class MainWindow : Window
{
    public ObservableCollection<ItemContainer> items { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        items = new ObservableCollection<ItemContainer>();

        items.Add(new ItemContainer() { containerItems = new List<string>() { "Item1", "Item2", "Item3" } });
        items.Add(new ItemContainer() { containerItems = new List<string>() { "Item4", "Item5", "Item6" } });

        this.DataContext = this;
    }


    public static T FindAncestorOrSelf<T>(DependencyObject obj)
        where T : DependencyObject
    {
        while (obj != null)
        {
            T objTest = obj as T;

            if (objTest != null)
                return objTest;

            obj = VisualTreeHelper.GetParent(obj);
        }
        return null;
    }

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListViewItem lvItem = FindAncestorOrSelf<ListViewItem>(sender as ComboBox);
        ListView listView = ItemsControl.ItemsControlFromItemContainer(lvItem) as ListView;
        int index = listView.ItemContainerGenerator.IndexFromContainer(lvItem);
        Console.WriteLine(index.ToString());
    }
}

And the simple model class:

public class ItemContainer
{
    public List<string> containerItems { get; set; }
}

That's about it. Have fun!

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