WPF访问ListView / GridView中的子项

时间:2014-09-10 18:20:10

标签: wpf listview gridview subitem

我试图访问listview子项。我必须动态地将列插入此ListView / GridView,因为该程序访问具有不同值类型的多个数据库。 如果需要我可以将数据库分成多个选项卡,但为了方便使用,我宁愿不采取这种方式。

我一直在寻找大约3-4天的解决方案。此类组织来自OleDB查询的子项数据。以下是我使用的代码片段:

    public class Repair
    {
        public string RP { get; set; }
        public string SN { get; set; }
        public DateTime REC { get; set; }
        public DateTime START { get; set; }
        public string CUST { get; set; }
        public string SP { get; set; }
        public string TECH { get; set; }
        public string STATUS { get; set; }
        public string MODEL { get; set; }
        public string NOTES { get; set; }
        public DateTime ACCUSED { get; set; }
        public string ACCNOTES { get; set; }
        public int ID { get; set; }
    }
    public IList<Repair> OpenRepair { get; set; }

然后使用以下代码段将数据插入ListView:

var gridView = new GridView();
this.searchListView.View = gridView;
gridView.Columns.Add(new GridViewColumn { Header = "RMA #", DisplayMemberBinding = new System.Windows.Data.Binding("RP") });
gridView.Columns.Add(new GridViewColumn { Header = "Serial", DisplayMemberBinding = new System.Windows.Data.Binding("SN") });
gridView.Columns.Add(new GridViewColumn { Header = "Recieved", DisplayMemberBinding = new System.Windows.Data.Binding("REC") });
gridView.Columns.Add(new GridViewColumn { Header = "Start", DisplayMemberBinding = new System.Windows.Data.Binding("START") });
gridView.Columns.Add(new GridViewColumn { Header = "Customer", DisplayMemberBinding = new System.Windows.Data.Binding("CUST") });
gridView.Columns.Add(new GridViewColumn { Header = "Sales Person", DisplayMemberBinding = new System.Windows.Data.Binding("SP") });
gridView.Columns.Add(new GridViewColumn { Header = "Technician", DisplayMemberBinding = new System.Windows.Data.Binding("TECH") });
gridView.Columns.Add(new GridViewColumn { Header = "Status", DisplayMemberBinding = new System.Windows.Data.Binding("STATUS") });
gridView.Columns.Add(new GridViewColumn { Header = "Repair Notes", DisplayMemberBinding = new System.Windows.Data.Binding("NOTES") });
gridView.Columns.Add(new GridViewColumn { Header = "Accidental Used Date", DisplayMemberBinding = new System.Windows.Data.Binding("ACCUSED") });
gridView.Columns.Add(new GridViewColumn { Header = "Accidental Notes", DisplayMemberBinding = new System.Windows.Data.Binding("ACCNOTES") });
gridView.Columns.Add(new GridViewColumn { Header = "ID", DisplayMemberBinding = new System.Windows.Data.Binding("ID"), Width = 0 });
using (OleDbConnection cn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:\***"))
{
    cmd.Connection = cn;
    cmd.CommandText = sqlstatement;
    try
    {
         cn.Open();
         dr = cmd.ExecuteReader();
         if (dr.HasRows)
         {
             while (dr.Read())
             {
                  OpenRepair = new List<Repair>();
                  if (dr[10].ToString() == "True")
                  {
                        OpenRepair.Add(
                        new Repair()
                        {
                           RP = dr[0].ToString(),
                           SN = dr[1].ToString(),
                           REC = Convert.ToDateTime(dr[2].ToString()).Date,
                           START = Convert.ToDateTime(dr[3].ToString()).Date,
                           CUST = dr[4].ToString(),
                           SP = dr[5].ToString(),
                           TECH = dr[6].ToString(),
                           STATUS = dr[7].ToString(),
                           MODEL = dr[8].ToString(),
                           NOTES = dr[9].ToString(),
                           ACCUSED = Convert.ToDateTime(dr[11].ToString()),
                           ACCNOTES = dr[12].ToString(),
                           ID = Convert.ToInt32(dr[13].ToString())
                        });
                    }
                    else
                    {
                         OpenRepair.Add(
                         new Repair()
                         {
                             RP = dr[0].ToString(),
                             SN = dr[1].ToString(),
                             REC = Convert.ToDateTime(dr[2].ToString()).Date,
                             START = Convert.ToDateTime(dr[3].ToString()).Date,
                             CUST = dr[4].ToString(),
                             SP = dr[5].ToString(),
                             TECH = dr[6].ToString(),
                             STATUS = dr[7].ToString(),
                             MODEL = dr[8].ToString(),
                             NOTES = dr[9].ToString(),
                             ID = Convert.ToInt32(dr[13].ToString())
                          });
                      }
                  searchListView.Items.Add(OpenRepair);
               }

ListView后面的XAML:

<ListView ItemsSource="{Binding Repair}" SelectionMode="Single" x:Name="searchListView" Margin="0,63,0,0" Background="DarkGray" MouseDoubleClick="searchListView_MouseDoubleClick">
                    <ListView.View>
                        <GridView />
                    </ListView.View>
                </ListView>

我试图通过几种方法获取ListView / GridView中的Subitem值。它对这两个代码都没有成功:

                Repair lvi = (Repair)searchListView.SelectedItems[0];
                System.Windows.MessageBox.Show(lvi.RP + " " + lvi.SN + " " + lvi.SP);

&安培;

          Repair lvi = (Repair)this.customersListView.SelectedItem;
          MessageBox.Show(string.Format("Repair: {1}{0}Serial Number:{2}", Environment.NewLine, lvi.RP, lvi.SN));

甚至尝试过Windows窗体方法,这显然无效。

有人可以请至少指出我正确的方向吗?我已经获得的错误消息是有道理的,因为它无法从对象Generic List强制转换为类Repair,但是,因为我对WPF很新,所以我很难理解如何传递此消息!

2 个答案:

答案 0 :(得分:1)

我测试了你的代码,它对我有用,所以你可能在你没有表现出来的部分有一些错误。但是让我试着用你的MVVM模式来赢得你,从长远来看它会让你的生活变得更加轻松......

ViewModel和Repair类(用于字符串的交换日期时间):

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

namespace WpfApplication1.Models
{
    public class ListViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public ObservableCollection<Repair> Repairs { get; private set; }
        public ActionCommand DoubleClickCommand { get; private set; }

        private Repair _selectedRepair;
        public Repair SelectedRepair { get { return _selectedRepair; } set { _selectedRepair = value; OnPropertyChanged("SelectedRepair"); } }

        public ListViewModel()
        {
            this.Repairs = new ObservableCollection<Repair>();
            this.Repairs.Add(new Repair { RP = "1000", SN = "A", START = DateTime.Today.ToString("d"), CUST = "C", ID = 0 });
            this.Repairs.Add(new Repair { RP = "2000", SN = "D", REC = DateTime.Today.AddDays(-2).ToString("d"), CUST = "E", ID = 1 });

            this.DoubleClickCommand = new ActionCommand(DoubleClick);
        }

        private void DoubleClick()
        {
            // do whatever (probably not show a MessageBox..)
            MessageBox.Show(string.Format("Repair: {1}{0}Serial Number:{2}", Environment.NewLine, this.SelectedRepair.RP, this.SelectedRepair.SN));
        }
    }

    public class ActionCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        private Action _action;
        public ActionCommand(Action action) { _action = action; }
        public bool CanExecute(object parameter) { return true; }
        public void Execute(object parameter) { if (_action != null) _action(); }
    }

    public class Repair
    {
        public string RP { get; set; }
        public string SN { get; set; }
        public string REC { get; set; }
        public string START { get; set; }
        public string CUST { get; set; }
        public string SP { get; set; }
        public string TECH { get; set; }
        public string STATUS { get; set; }
        public string MODEL { get; set; }
        public string NOTES { get; set; }
        public string ACCUSED { get; set; }
        public string ACCNOTES { get; set; }
        public int ID { get; set; }
    }
}

观点:

<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:models="clr-namespace:WpfApplication1.Models"  
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        Title="MainWindow" Height="350" Width="500">
    <Window.DataContext>
        <models:ListViewModel />
    </Window.DataContext>
    <ListView ItemsSource="{Binding Repairs}" SelectedItem="{Binding SelectedRepair}" SelectionMode="Single" Margin="0,63,0,0" Background="DarkGray">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick">
                <i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <ListView.View>
            <GridView>
                <GridViewColumn Header="RMA #" DisplayMemberBinding="{Binding RP}" />
                <GridViewColumn Header="Serial" DisplayMemberBinding="{Binding SN}"/>
                <GridViewColumn Header="Recieved" DisplayMemberBinding="{Binding REC}"/>
                <GridViewColumn Header="Start" DisplayMemberBinding="{Binding START}"/>
                <GridViewColumn Header="Customer" DisplayMemberBinding="{Binding CUST}"/>
                <GridViewColumn Header="Sales Person" DisplayMemberBinding="{Binding SP}"/>
                <GridViewColumn Header="Technician" DisplayMemberBinding="{Binding TECH}"/>
                <GridViewColumn Header="Status" DisplayMemberBinding="{Binding STATUS}"/>
                <GridViewColumn Header="Repair Notes" DisplayMemberBinding="{Binding NOTES}"/>
                <GridViewColumn Header="Accidental Used Date" DisplayMemberBinding="{Binding ACCUSED}"/>
                <GridViewColumn Header="Accidental Notes" DisplayMemberBinding="{Binding ACCNOTES}"/>
                <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" Width="0" />
            </GridView>
        </ListView.View>
    </ListView>
</Window>

答案 1 :(得分:0)

根据我的评论,这里有一个更完整的答案,供将来参考。

所选对象(SelectedItem显示的对象)可通过SelectedValue获得。

当您使用List时,您应该执行以下操作:

((List<Repair>)searchListView.SelectedValue)[0].SN