【问题标题】:C# combobox selected item changing (from option clicked to bottom option)C# 组合框选定项更改(从单击选项到底部选项)
【发布时间】:2019-09-11 13:28:09
【问题描述】:

当我选择一个选项或更改组合框中的 selectedindex 时,它会在切换到所选项目之前显示为底部项目。

这是问题的视频:https://imgur.com/gallery/5CTuSjI

我对 c# 还很陌生,所以如果我的代码没有优化/整洁,我深表歉意。

代码中有一些敏感项目,例如 API 密钥和安全信息,因此会丢失一些。

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
namespace Yugioh_Program
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Events

        private void Label2_Click(object sender, EventArgs e)
        {

        }

        private void TextBox1_TextChanged(object sender, EventArgs e)
        {

        }

加载功能(从电子表格设置组合框的值)

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] _scopes = { SheetsService.Scope.Spreadsheets };
            string _applicationName = "My Application Name from Google API Project ";
            string _spreadsheetId = "CONFIDENTIAL";
            string sheet = "ALL";

            SheetsService service;
            GoogleCredential credential;

            using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
            {
                credential = GoogleCredential.FromStream(stream)
                    .CreateScoped(_scopes);
            }

            service = new SheetsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = _applicationName,
            });

            List<List<string>> searchedCards = new List<List<string>>();

            var range = $"{sheet}!B2:G";
            var request = service.Spreadsheets.Values.Get(_spreadsheetId, range);

            var response = request.Execute();
            var values = response.Values;
            if (values != null && values.Count > 0)
            {
                foreach (var row in values)
                {
                    searchedCards.Add(new List<string> { row[0].ToString(), row[1].ToString(), row[2].ToString(), row[3].ToString(), row[4].ToString(), row[5].ToString() });
                }

            }

            Cards item = new Cards();

            List<string> addedCards = new List<string>();
            List<string> addedCardsNoDupe = new List<string>();

            foreach (List<string> subList in searchedCards)
            {
                addedCards.Add(subList[0]);
                addedCardsNoDupe = addedCards.Distinct().ToList();
            }
            foreach (string addedCard in addedCardsNoDupe)
            {
                item.Text = addedCard;
                item.Value = addedCard;
                NameSearch.Items.Add(item);
            }
        }

SelectedIndexChanged(当上述组合框的内容发生变化时,从电子表格中提取值,使用在上述组合框中选择的选项过滤它们并将它们添加到列表中。


        private void NameSearch_SelectedIndexChanged(object sender, EventArgs e)
        {

            // API call
            string[] _scopes = { SheetsService.Scope.Spreadsheets };
            string _applicationName = "My Application Name from Google API Project ";
            string _spreadsheetId = "CONFIDENTIAL";
            string sheet = "ALL";

            SheetsService service;
            GoogleCredential credential;

            using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
            {
                credential = GoogleCredential.FromStream(stream)
                    .CreateScoped(_scopes);
            }

            service = new SheetsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = _applicationName,
            });

            List<List<string>> searchedCards = new List<List<string>>();
            List<List<string>> searchedSets = new List<List<string>>();

            var range = $"{sheet}!B2:G";
            var request = service.Spreadsheets.Values.Get(_spreadsheetId, range);

            var response = request.Execute();
            var values = response.Values;
            if (values != null && values.Count > 0)
            {
                foreach (var row in values)
                {
                    searchedCards.Add(new List<string> { row[0].ToString(), row[1].ToString(), row[2].ToString(), row[3].ToString(), row[4].ToString(), row[5].ToString() });
                }
                foreach (List<string> subList in searchedCards)
                {
                    //   name / set / rarity / edition / quantity / row number
                    searchedSets.Add(new List<string> { subList[0].ToString(), subList[1].ToString(), subList[2].ToString(), subList[3].ToString(), subList[4].ToString(), subList[5].ToString() });
                }
            }

            string selectedCard = NameSearch.Text.ToString();
            label1.Text = selectedCard;
            SetSearch.Items.Clear();

            Cards item = new Cards();

            foreach (List<string> subSet in searchedSets)
            {
                if (selectedCard == subSet[0])
                {
                    string addedText = subSet[0] + " | " + subSet[1] + " | " + subSet[2] + " | " + subSet[3];

                    item.Text = addedText;
                    item.Value = 0;

                    SetSearch.Items.Add(item);

                }
            }
        }
    }
}

当我从第一个组合框中选择“黑魔法师”时,预期的结果是 selectedCard 将 =“黑魔法师”,第二个组合框将被它过滤。

相反,在第一个组合框显示所选选项之前,第一个组合框中的最后一个列表项(“星尘龙”)被选中,并且 selectedCard =“星尘龙”而不是预期的所选项目。

请求代码帮助的新方法,所以如果您需要更多信息/上下文等,请询问:)

【问题讨论】:

  • 您可能应该使用NameSearch.SelectedItemNameSearch.SelectedValue,将其类型转换为Cards,而不是组合框的Text 属性,在SelectedIndexChanged 被触发之前可能不会更新。
  • 我注意到的一件事是 addedCardsNoDupe = addedCards.Distinct().ToList();可能应该移到 foreach 循环之外,否则你可能会得到重复。
  • @JeroenvanLangen 尝试了 .SelectedItem 没有任何变化,但 .SelectedValue 给了我一个错误:System.NullReferenceException: '对象引用未设置为对象的实例。'

标签: c# winforms combobox google-sheets-api


【解决方案1】:

向表单添加一个成员级布尔标志,指示表单正在加载。在 NameSearch_SelectedIndexChanged 事件处理程序中,检查表单是否正在加载;如果只是退出处理程序;否则,继续。

public partial class Form1 : Form
{

    boolean _formLoading;

    private void Form1_Load(object sender, EventArgs e)
    {
        _formLoading = true;
        ...
        ...
        ...
        _formLoading = false;
    }

    private void NameSearch_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (_formLoading) return;
        ...
        ...
        ...
    }
}

【讨论】:

  • 添加了建议的代码,程序的响应没有变化。我将尝试录制视频并将其添加到我的问题中,因为描述起来有点棘手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多