Binding items into ListBox multiple columns

2019-05-27 01:19发布

问题:

I am trying to add my data into multiple columns ListBox, I did it but I am facing a hard problem when trying to retrieve the Data from the list box. is there a way to put an object instead of text into a listBox row?

<ListView Name="listBox1" ItemsSource="{Binding Items}" Margin="28,28,68,67" FlowDirection="RightToLeft" MouseDoubleClick="listBox1_MouseDoubleClick">
        <ListView Name="listBox1" ItemsSource="{Binding Items}" Margin="28,28,68,67" FlowDirection="RightToLeft" MouseDoubleClick="listBox1_MouseDoubleClick">
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Header="a" Width="100" DisplayMemberBinding="{Binding Path=ID}" />
                    <GridViewColumn Header="b" Width="100" DisplayMemberBinding="{Binding Path=Name}" />
                    <GridViewColumn Header="c" Width="100" DisplayMemberBinding="{Binding Path=F}" />
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

and this is the code

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    public sealed class MyListBoxItem
    {
        public string Field1 { get; set; }
        public string Field2 { get; set; }
        public string Field3 { get; set; }
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Students st = new Students(1, "name","anything");
        listBox1.ItemsSource = new List(new[] { st });
    }

    private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        object ob = listBox1.SelectedItem;
        string i = ((MyListBoxItem)listBox1.SelectedItem).Field1;
    }
}

and here is the class Students

 class Students
{
    int id;
    string name;
    string f;

    public Students(int id, string name,string f)
    {
        this.id = id;
        this.name = name;
        this.f = f;
    }
    public int ID
    {
        get { return id; }
        set { id = value; }
    }
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string F
    {
        get { return f; }
        set { f = value; }
    }
}

回答1:

Don't use listBox1.Items.Add(....). Rather use listBox1.ItemsSource = new List(new[] {st});

Then change Your DisplayMemberBindings to "Id", "Name" respectively.

There is no need for the ListBoxItem Class.

== EDIT ==

You were very close to getting it perfectly. I've attached below how it should work. The important things to notice are the Bindings in the ListView for ItemsSource and SelctedITem, and setting IsSynchronisedWithCurrentItem to true.

Also, in the bottom two rows ofthe grid, I've shown two different ways of binding to the selected item, one using "/" notation, and the other using a property on the ViewModel

XAML

<Window x:Class="StackOverflow11087468.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>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
            <ListView Name="listBox1"
                      Grid.Row="0"
                      ItemsSource="{Binding Students}"
                      SelectedItem="{Binding SelectedStudent}"
                      IsSynchronizedWithCurrentItem="True"
                      Margin="28,28,68,67"
                      FlowDirection="RightToLeft">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="a"
                                            Width="100"
                                            DisplayMemberBinding="{Binding Path=ID}" />
                            <GridViewColumn Header="b"
                                            Width="100"
                                            DisplayMemberBinding="{Binding Path=Name}" />
                            <GridViewColumn Header="c"
                                            Width="100"
                                            DisplayMemberBinding="{Binding Path=F}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock>ID</TextBlock>
            <TextBox Text="{Binding Students/ID}" />            
        </StackPanel>

        <StackPanel Grid.Row="2"
                    Orientation="Horizontal">
            <TextBlock>ID</TextBlock>
            <TextBox Text="{Binding SelectedStudent.ID}" />
        </StackPanel>
    </Grid>
</Window>

Main.Window.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace StackOverflow11087468
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = new ViewModel();
        }
    }
}

ViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace StackOverflow11087468
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<Student> Students { get; set; }

        public ViewModel()
        {
            this.Students = new ObservableCollection<Student>();
            Students.Add(new Student(98760987, "Student1", "F"));
            Students.Add(new Student(98760988, "Student22", "M"));
        }

        public Student SelectedStudent
        {
            get { return _selectedStudent; }
            set
            {
                _selectedStudent = value;
                RaisePropertyChanged("SelectedStudent");
            }
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private Student _selectedStudent;
    }
}