C# 如何根据下载的文件更改datagridview单元格文本?

C# 如何根据下载的文件更改datagridview单元格文本?,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,在构造函数中 public Form1() { InitializeComponent(); label2.Visible = false; label3.Visible = false; label4.Visible = false; label7.Visible = false; tbxMainDownloadPath.Text

在构造函数中

public Form1()
        {
            InitializeComponent();

            label2.Visible = false;
            label3.Visible = false;
            label4.Visible = false;
            label7.Visible = false;

            tbxMainDownloadPath.Text = Properties.Settings.Default.LastSelectedFolder;
            if (tbxMainDownloadPath.Text != "")
                downloadDirectory = tbxMainDownloadPath.Text;

            tracker = new DownloadProgressTracker.DownloadProgress(50, TimeSpan.FromMilliseconds(500));
            string[] countries = File.ReadAllLines(@"CountriesNames.txt");
            string[] countriesCodes = File.ReadAllLines(@"CountriesCodes.txt");
            foreach (string country in countries)
            {
                countryList.Add(country);
                string countryPath = Path.Combine(downloadDirectory, country);
                if (!Directory.Exists(countryPath))
                    Directory.CreateDirectory(countryPath);
            }
            foreach (string code in countriesCodes)
            {
                codesList.Add(code);
            }
            codeToFullNameMap = codesList
                .Select((code, index) => index)
                .ToDictionary(
                              keySelector: index => codesList[index],
                              elementSelector: index => countryList[index]);

            lines = File.ReadAllLines(@"links.txt");

            for (int i = 0; i < lines.Length; i++)
            {
                RichTextBoxExtensions.AppendText(true, richTextBox1, "Ready: ", Color.Red, 8.25f);
                richTextBox1.AppendText(lines[i] + (i < lines.Length - 1 ? Environment.NewLine : String.Empty));
            }

            for (int i = 0; i < countriesCodes.Length; i++)
            {
                dataGridView1.ColumnCount = 2;
                dataGridView1.Columns[0].Name = "Status";
                dataGridView1.Columns[1].Name = "Country";
                var countryName = codeToFullNameMap[countriesCodes[i]];
                string[] row = new string[] { "Ready", countryName };
                dataGridView1.Rows.Add(row);
                DataGridViewLinkColumn dgvLink = new DataGridViewLinkColumn();
                dgvLink.UseColumnTextForLinkValue = true;
                dgvLink.LinkBehavior = LinkBehavior.SystemDefault;
                dgvLink.HeaderText = "Link Data";
                dgvLink.Name = "SiteName";
                dgvLink.LinkColor = Color.Blue;
                dgvLink.TrackVisitedState = true;
                dgvLink.Text = lines[i];
                dgvLink.UseColumnTextForLinkValue = true;
                dataGridView1.Columns.Add(dgvLink);
            }
            this.dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

            DataGridViewCellStyle mystyle = new DataGridViewCellStyle();
            mystyle.SelectionBackColor = Color.White;
            mystyle.SelectionForeColor = Color.Red;
            dataGridView1.DefaultCellStyle = mystyle;

            dataGridView1.RowHeadersVisible = false;
            dataGridView1.AllowUserToAddRows = false;
            dataGridView1.BackgroundColor = System.Drawing.SystemColors.Control;

            dataGridView1.Columns[0].DefaultCellStyle.ForeColor = Color.Red;
        }
下载文件后

问题是它始终是单元格[0] 如何找到已下载的链接/文件并将单元格值更改为正确的索引

例如,如果完成的事件中有错误,我想将正确的单元格索引值更改为红色的“error”。如果文件下载没有任何问题,请将右侧单元格索引更改为绿色的“已下载”

问题是如何找到正确的单元格索引

以及注册已完成事件的方法。 我从按钮单击事件调用此方法

private void DownloadFile()
        {
            if (_downloadUrls.Any())
            {
                WebClient client = new WebClient();
                client.DownloadProgressChanged += client_DownloadProgressChanged;
                client.DownloadFileCompleted += client_DownloadFileCompleted;

                url = _downloadUrls.Dequeue();

                if (url.Contains("animated") && url.Contains("infra"))
                {
                    string startTag = "animated/";
                    string endTag = "/infra";

                    int index = url.IndexOf(startTag);
                    int index1 = url.IndexOf(endTag);

                    fname = url.Substring(index + 9, index1 - index - 9);
                    var countryName = codeToFullNameMap[fname];
                    downloadDirectory = tbxMainDownloadPath.Text;
                    downloadDirectory = Path.Combine(downloadDirectory, countryName);
                }
                else
                {
                    fname = "Tempfile";
                    downloadDirectory = tbxMainDownloadPath.Text;
                }

                client.DownloadFileAsync(new Uri(url), downloadDirectory + "\\" + fname + ".gif");
                lastDownloadedFile = downloadDirectory + "\\" + fname + ".gif";

                return;
            }

            // End of the download
            label2.Text = "All files have been downloaded";
        }
最后一个事件是progresschanged

void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
            pBarFileProgress.Value = (int)(tracker.GetProgress() * 100.0);
            label3.Text = e.BytesReceived + "/" + e.TotalBytesToReceive;
            label7.Text = tracker.GetBytesPerSecondString();
            label2.Text = "Downloading";
            label4.Text = downloadDirectory + "\\" + fname + ".gif";
        }
以及将URL添加到队列的downloadfile方法

private void downloadFile(IEnumerable<string> urls)
        {
            foreach (var url in urls)
            {
                _downloadUrls.Enqueue(url);
            }

            // Starts the download
            btnStart.Text = "Downloading...";
            btnStart.Enabled = false;
            pBarFileProgress.Visible = true;

            DownloadFile();

            label2.Visible = true;
            label3.Visible = true;
            label4.Visible = true;
            label7.Visible = true;
            label3.Text = "";
            label7.Text = "";
            label2.Text = "";
            label4.Text = "";
        }
private void下载文件(IEnumerable URL)
{
foreach(url中的变量url)
{
_下载url.Enqueue(url);
}
//开始下载
btnStart.Text=“下载…”;
btnStart.Enabled=false;
pBarFileProgress.Visible=true;
下载文件();
label2.Visible=true;
标签3.可见=真;
label4.可见=真;
标签7.可见=真实;
标签3.Text=“”;
标签7.Text=“”;
标签2.Text=“”;
label4.Text=“”;
}

代码中存在多个问题。我将只关注与你的问题相关的问题。此外,我正在尽可能多地保留您自己的代码,以便您能够更好地理解您的代码和建议的代码之间的差异

  • 您应该在构造函数中只设置一次网格,然后向其中添加所需的行数据。目前,您正在重复设置列—这就是DataGridViewLinkColumn工作的原因
  • 您的代码:

    for (int i = 0; i < countriesCodes.Length; i++)
    {
        dataGridView1.ColumnCount = 2;
        dataGridView1.Columns[0].Name = "Status";
        dataGridView1.Columns[1].Name = "Country";
        var countryName = codeToFullNameMap[countriesCodes[i]];
        string[] row = new string[] { "Ready", countryName };
        dataGridView1.Rows.Add(row);
        DataGridViewLinkColumn dgvLink = new DataGridViewLinkColumn();
        dgvLink.UseColumnTextForLinkValue = true;
        dgvLink.LinkBehavior = LinkBehavior.SystemDefault;
        dgvLink.HeaderText = "Link Data";
        dgvLink.Name = "SiteName";
        dgvLink.LinkColor = Color.Blue;
        dgvLink.TrackVisitedState = true;
        dgvLink.Text = lines[i];
        dgvLink.UseColumnTextForLinkValue = true;
        dataGridView1.Columns.Add(dgvLink);
    }
    
    dataGridView1.ColumnCount = 2;
    dataGridView1.Columns[0].Name = "Status";
    dataGridView1.Columns[1].Name = "Country";
    
    DataGridViewLinkColumn dgvLink = new DataGridViewLinkColumn();
    dgvLink.UseColumnTextForLinkValue = true;
    dgvLink.LinkBehavior = LinkBehavior.SystemDefault;
    dgvLink.HeaderText = "Link Data";
    dgvLink.Name = "SiteName";
    dgvLink.LinkColor = Color.Blue;
    dgvLink.TrackVisitedState = true;
    dgvLink.UseColumnTextForLinkValue = false;
    dataGridView1.Columns.Add(dgvLink);
    dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    
    for (int i = 0; i < countriesCodes.Length; i++) {
        var countryName = codeToFullNameMap[countriesCodes[i]];
        string[] row = new string[] { "Ready", countryName, lines[i] };
        dataGridView1.Rows.Add(row);
    }
    
    DataGridViewRow row = new DataGridViewRow();
    dataGridView1.Rows[0].Cells[0].Value = 
    dataGridView1.Rows[0].Cells[0].Style.SelectionForeColor = Color.Green;
    
    var row = dataGridView1.Rows.Cast<DataGridViewRow>()
                .First(r => r.Cells[2].Value.Equals(url));
    row.Cells[0].Value = "Downloaded";
    row.Cells[0].Style.ForeColor = Color.Green;
    
    更正代码:

    for (int i = 0; i < countriesCodes.Length; i++)
    {
        dataGridView1.ColumnCount = 2;
        dataGridView1.Columns[0].Name = "Status";
        dataGridView1.Columns[1].Name = "Country";
        var countryName = codeToFullNameMap[countriesCodes[i]];
        string[] row = new string[] { "Ready", countryName };
        dataGridView1.Rows.Add(row);
        DataGridViewLinkColumn dgvLink = new DataGridViewLinkColumn();
        dgvLink.UseColumnTextForLinkValue = true;
        dgvLink.LinkBehavior = LinkBehavior.SystemDefault;
        dgvLink.HeaderText = "Link Data";
        dgvLink.Name = "SiteName";
        dgvLink.LinkColor = Color.Blue;
        dgvLink.TrackVisitedState = true;
        dgvLink.Text = lines[i];
        dgvLink.UseColumnTextForLinkValue = true;
        dataGridView1.Columns.Add(dgvLink);
    }
    
    dataGridView1.ColumnCount = 2;
    dataGridView1.Columns[0].Name = "Status";
    dataGridView1.Columns[1].Name = "Country";
    
    DataGridViewLinkColumn dgvLink = new DataGridViewLinkColumn();
    dgvLink.UseColumnTextForLinkValue = true;
    dgvLink.LinkBehavior = LinkBehavior.SystemDefault;
    dgvLink.HeaderText = "Link Data";
    dgvLink.Name = "SiteName";
    dgvLink.LinkColor = Color.Blue;
    dgvLink.TrackVisitedState = true;
    dgvLink.UseColumnTextForLinkValue = false;
    dataGridView1.Columns.Add(dgvLink);
    dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    
    for (int i = 0; i < countriesCodes.Length; i++) {
        var countryName = codeToFullNameMap[countriesCodes[i]];
        string[] row = new string[] { "Ready", countryName, lines[i] };
        dataGridView1.Rows.Add(row);
    }
    
    DataGridViewRow row = new DataGridViewRow();
    dataGridView1.Rows[0].Cells[0].Value = 
    dataGridView1.Rows[0].Cells[0].Style.SelectionForeColor = Color.Green;
    
    var row = dataGridView1.Rows.Cast<DataGridViewRow>()
                .First(r => r.Cells[2].Value.Equals(url));
    row.Cells[0].Value = "Downloaded";
    row.Cells[0].Style.ForeColor = Color.Green;
    
    var row=dataGridView1.Rows.Cast()
    .First(r=>r.Cells[2].Value.Equals(url));
    行。单元格[0]。Value=“已下载”;
    行。单元格[0]。Style.ForeColor=Color.Green;
    

    这将使您获得所需的行为。如您所见,变量
    应该具有与
    url
    对应的正确行。您可以根据需要更改所需的单元格文本和样式-以处理错误案例和成功下载案例

    您的
    DataGridViewLinkColumn.CellContentClick
    事件处理程序的外观。希望事件处理程序将显示注册
    client\u DownloadFileCompleted
    的代码,否则您还应该显示注册
    client\u DownloadFileCompleted
    事件并与itFYI相关的代码,您循环添加数据的构造函数代码没有意义。您应该分离设置列和添加行数据的代码(最好是分离到单独的函数中)。如果有100行,那么当前将列设置100次,这是完全不必要的。为了解决问题,还需要将一些
    UserState
    数据传递给异步下载任务,如链接本身,因此,您可以在
    DownloadFileCompleted
    事件上搜索该表,并更新相应行的第一行column@Vikhram用我注册已完成事件的部分编辑了我的问题。@Vikhram我将尝试这样做。但是,如果你能在以后发布这两个问题的答案,构造函数和完成的事件,那就太好了。@Vikhram我以前使用过async await和task,但现在不知道如何使用我的代码。