从列表中填充下拉框

16

新手上路, 我目前正在制作一个表单,其中包含一个组合框,您可以在其中查看并选择几个查理·布朗电视特别节目,并查看其描述、评级、运行时间等信息。我快要完成了,但在填充组合框方面还有些问题,希望能得到一些帮助和指导。我已经查看了其他人做过的几件事情,但是我还不够知识渊博,无法从迄今为止所见到的内容中推断出答案。

现在我正在尝试: 1. 从您的加载方法中获取列表 2. 循环遍历它们 3. 访问我的组合框,以使用列表中的时间填充该框。

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Globalization;//Used for Sting.ToUpperCase...
using System.Threading;

using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...


namespace a100___GUI___VideoStoreSelections
{
public partial class FormMovieLookUp : Form
{
    private const String FILE_NAME = "txt_movieDescriptions.txt";//connect to text file in debug

    private List<Listing> films { get; set; }

    public FormMovieLookUp()
    {
        InitializeComponent();
    }

    private void cmbMovieListingBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        txtTitleBox.Text = cmbMovieListingBox.SelectedItem.ToString();
    }

    //ToolBox -- my program specific tools
    public List<Listing> LoadListings()//load movie descriptions as list
    {
        StreamReader fileIn = new StreamReader(FILE_NAME);
        List<Listing> entries = new List<Listing>();

        //loop through every line of the file
        while (!fileIn.EndOfStream)
        {
            String line = fileIn.ReadLine();
            String[] pieces = line.Split(':');

            if (pieces.Length < 4) continue;//error handling - set to length of text items

            Listing myListing = new Listing(pieces[0], pieces[1], pieces[2], pieces[3]);
            entries.Add(myListing);
        }
        fileIn.Close();
        return entries;
    }

    private void FormMovieLookUp_Load_1(object sender, EventArgs e)
    {
        films = LoadListings();
        foreach (Listing film in films)
        {
            Console.WriteLine(film);
            cmbMovieListingBox.Items.Add(film.GetFilmTitle());
        }
    }
}
}

清单.CS

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

namespace a100___GUI___VideoStoreSelections
{

public class Listing
{
    private String filmTitle;
    private String description;
    private String filmRunTime;
    private String filmRating;

    public Listing(String filmTitle, String description, String filmRunTime, String filmRating)
    {
        this.filmTitle = filmTitle;
        this.description = description;
        this.filmRunTime = filmRunTime;
        this.filmRating = filmRating;
    }

    public String GetFilmTitle() { return filmTitle; }
    public String GetDescription() { return description; }
    public String GetFilmRunTime() { return filmRunTime; }
    public String GetFilmRating() { return filmRating; }



}

所以这就是我试图做的来填充我的组合框。任何帮助都将受到感激。


2
你的代码已经使用了循环并访问了组合框。到底是什么阻止你获取列表,循环遍历它,并将每个元素的文本添加到组合框中? - nvoigt
当我运行它(点击绿色箭头进行编译/测试)时,框没有填充。这让我觉得我不知道自己在做什么。一般来说,作为一个新手,我可以告诉你我不知道自己在做什么。我希望组合框能够填充文本文档中每行的第一段内容。 - Chezshire
7个回答

23

我会将List<Listing>保留在类级别上,以便在用户单击时可以访问它。我还会将其放入自己的线程中,而不是直接加载事件中。如果是一个长时间的过程,你会挂起界面。

private List<Listing> films { get; set; }

加载

films = LoadListings();
foreach (Listing film in films)
{
    cmbMovieListingBox.Items.Add(film.GetFilmTitle());
}

当用户选择该项时

Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).FistOrDefault();

if (film != null)
{
    //do work
}

我会尝试并回报。谢谢。 - Chezshire
我尝试过这个,但是我无法让它工作。它看起来应该可以工作,但对于我来说却没有。感谢您的帮助。您太棒了。 - Chezshire
你能把你的代码发出来吗?这样我就可以看看为什么它对你不起作用了。 - Tsukasa
我已更新代码,展示我最近尝试实现您的建议的代码。我把所有的代码都放到了form1.cs文件中。错误发生在第69行:无法声明“film”,因为它会改变子级中使用的“film”;错误2:'System.Collections.Generic.IEnumerable<a100___GUI___VideoStoreSelections.Listing>'不包含“FistOrDefault”的定义,并且找不到接受类型为'System.Collections.Generic.IEnumerable<a100___GUI___VideoStoreSelections.Listing>'的第一个参数的任何扩展方法'FistOrDefault'(您是否缺少一个using指令/程序集引用?) - Chezshire
我不知道具体是什么问题,但我和我的老师一起检查后,她说应该可以工作。她对文件进行了一些调试处理,打开关闭了几次,然后就可以正常运行了。她说问题在于最后一个方法根本没有运行 - 我们不确定为什么它没有运行,但当我们更换电脑后它自动启动了。现在一切都好了。有点神秘,我想。 - Chezshire
你可以直接将对象添加到组合框中。只需重写ToString方法以设置在组合框中如何呈现它。好处是,您可以使用组合框上的SelectedItem属性获取带有所有属性的整个对象。 - nivs1978

6
如果你问的是我想知道的问题,你需要在表单加载时添加类似于以下代码的内容:
foreach(Listing listing in LoadListings()){
    cmbMovieListingBox.Items.Add(listing.GetFilmTitle());
}

谢谢 - 我会尝试并回报。 - Chezshire
我尝试过这个,但是无法让它工作。感谢您的帮助 - 您也很棒。 - Chezshire

1

一行Tsukasa的代码无法工作,因为它写成了FistOrDefault()而不是FirstOrDefault()

Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).**First**OrDefault();

抱歉,我没有足够的积分来添加评论...

1

在视觉控件更新(例如ComboBox等)方面存在一个问题:你更愿意防止它们在每次数据更改(在你的情况下是每次添加项目)时重新绘制:

cmbMovieListingBox.BeginUpdate(); // <- Stop painting

try {
  // Adding new items into the cmbMovieListingBox 
  foreach(var item in LoadListings())
    cmbMovieListingBox.Items.Add(item.GetFilmTitle());
finally {
  cmbMovieListingBox.EndUpdate(); // <- Finally, repaint if required
}

我也尝试过这个,但是遗憾的是它产生了许多错误。它看起来真的很聪明,但我认为在我的实现尝试中出现了错误,当我将其放入私有void FormMovieLookUp_Load(object sender,EventArgs e)方法时出现了错误。谢谢。我知道这是什么,表单确实是非常令人恼火的东西。 - Chezshire

1

从列表声明中删除{get; set;}。它在那里不需要。

像这样定义你的类:

public class Listing
{
    private String filmTitle {get; set;}
    private String description {get; set;};
    …
}

在表单加载事件中,将ComboBoxDisplayMemberValueMember设置为“filmTitle”。
cmbMovieListingBox.DisplayMember = "filmTitle";
cmbMovieListingBox.ValueMember = "filmTitle"

最后,你必须将ComboBoxDataSource设置为列表。

cmbMovieListingBox.DataSource = films;

现在你已经完成了所有代码的编写,接下来你应该能够正常运行程序。


0

或许对某些人有所帮助。但在我的情况下,我不得不使用cmbMovieListingBox.Text而不是cmbMovieListingBox.SelectedValue(就像@Tsukasa的例子):

Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.Text)).FirstOrDefault();

if (film != null)
{
    //do work
}

还有使用FirstOrDefault()而不是FistOrDefault()

希望对某些人有所帮助。


0

这是我对代码所做的修改

int Count;
foreach(String i in Languages)
{
    LangComboBox.Items.Add(Languages[Count]);
    Count++;
}

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接