Loop through the second column of WPF ListView and retrieve value of ComboBox in each row

馋奶兔 提交于 2019-12-13 04:45:10

问题


I have a two-column ListView with CheckBoxes in the first column and ComboBoxes in the second column. I need to loop through the ComoboBoxes in the second column and retrieve the selected values (or indexes) from each ComboBox, along with some index or identifier of the ComboBox, and put the values in an array. For example, the layout looks like this:

COLUMN 1  COLUMN 2
========  ========
ChBx 1    Combo1
ChBx 2    Combo2

I need to grab the SelectedValue or SelectedIndex of each ComboBox in the second column and put it into an array in the right order. But, what I've found on the internet is to use: myListView.Items(0).SubItems(1).Text, to loop through the second column. However, my second column contains a ComboBox and I want its' value (not some Text property). Any ideas? My XAML markup is below.

            <ListView IsSynchronizedWithCurrentItem="True" Margin="0,0,10,10" Name="patternList" Height="139" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="112" BorderBrush="{x:Null}" BorderThickness="1" Background="White" >
                 <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="Pattern">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox Content="{Binding outContent}" 
                                                  ToolTip="{Binding outToolTip}"
                                                  IsThreeState="False"
                                                  IsChecked="{Binding Path=outIsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn Header="Freq" Width="55">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <ComboBox HorizontalContentAlignment="Center" 
                                                  Height="14" 
                                                  Padding="0" 
                                                  SelectionChanged="FrequencyChanged_OnSelectionChanged"
                                                  FontSize="10">
                                            <ComboBoxItem Content="0%"/>
                                            <ComboBoxItem Content="10%"/>
                                            <ComboBoxItem Content="20%"/>
                                            <ComboBoxItem Content="30%"/>
                                            <ComboBoxItem Content="40%"/>
                                            <ComboBoxItem Content="50%"/>
                                            <ComboBoxItem Content="60%"/>
                                            <ComboBoxItem Content="70%"/>
                                            <ComboBoxItem Content="80%"/>
                                            <ComboBoxItem Content="90%"/>
                                            <ComboBoxItem Content="100%"/>
                                        </ComboBox>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
   </ListView>

回答1:


Bind SelectedValue to a property in your ViewModel. And in the Setter of that property, also update the collection.

Second approach, in your FrequencyChanged_OnSelectionChanged event handler. You can keep updating your collection there too.




回答2:


From my perspective it would be better to generate items for the combobox in list item viewmodel, and bind to selected item in that view model. Below is the code that illustrates the approach.

XAML

<Window x:Class="ComboboxesInGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ComboboxesInGrid"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ListItems}" Margin="0,0,10,10" Name="patternList" BorderBrush="{x:Null}" BorderThickness="1" Background="White" >
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Pattern" Width="100">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox Content="{Binding outContent}" 
                                                  ToolTip="{Binding outToolTip}"
                                                  IsThreeState="False"
                                                  IsChecked="{Binding Path=outIsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Freq" Width="155">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox HorizontalContentAlignment="Center" 
                                                  Height="14" 
                                                  Padding="0" 
                                                  SelectedItem="{Binding outComboSelected}"
                                                  ItemsSource="{Binding outComboValues}"
                                                  FontSize="10">

                                    </ComboBox>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <TextBlock Grid.Row="1" Text="{Binding SelectedComboItems}" />
    </Grid>
</Window>

C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;


namespace ComboboxesInGrid
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ObservableCollection<ListItemViewModel> _listItems = new ObservableCollection<ListItemViewModel>();

        public string SelectedComboItems
        {
            get { return String.Join(",", _listItems.Select(li => $"{li.outContent}-{li.outIsChecked}-{li.outComboSelected}")); }
        }

        public ObservableCollection<ListItemViewModel> ListItems
        {
            get { return _listItems; }
            set { _listItems = value; OnProperyChanged(); }
        }

        public MainWindowViewModel()
        {
            AddListItem(new ListItemViewModel() { outContent = "ChBx 1 ", outToolTip="Tooooool", outIsChecked = false, outComboSelected="30%" });
            AddListItem(new ListItemViewModel() { outContent = "ChBx 2 ", outComboSelected = "70%" });

        }

        private void AddListItem(ListItemViewModel item)
        {
            item.PropertyChanged += (s, e) => OnProperyChanged(nameof(SelectedComboItems));
            _listItems.Add(item);
        }
    }

    public class ListItemViewModel : ViewModelBase
    {
        private string _outContent;

        public string outContent
        {
            get { return _outContent; }
            set { _outContent = value; OnProperyChanged(); }
        }


        private string _outToolTip;
        public string outToolTip
        {
            get { return _outToolTip; }
            set { _outToolTip = value; OnProperyChanged(); }
        }

        private bool? _outIsChecked;
        public bool? outIsChecked
        {
            get { return _outIsChecked; }
            set { _outIsChecked = value; OnProperyChanged(); }
        }

        private string _outComboSelected;
        public string outComboSelected
        {
            get { return _outComboSelected; }
            set { _outComboSelected = value; OnProperyChanged(); }
        }

        public IEnumerable<string> outComboValues
        {
            get
            {
                return Enumerable.Range(0, 11).Select(i => $"{i*10}%");
            }
        }
    }

    public class ViewModelBase : INotifyPropertyChanged
    {
        protected void OnProperyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }
}


来源:https://stackoverflow.com/questions/34235767/loop-through-the-second-column-of-wpf-listview-and-retrieve-value-of-combobox-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!