0

我有一个 tabControl,每次单击搜索按钮时都会在其中添加 tabPages。tabControl 对象还有一个 MouseDown 事件处理程序,以便在鼠标悬停在特定选项卡上并单击它时关闭选项卡。tabcontrol_MouseDown 方法还取消了在单击搜索按钮时启动的任务,因此该任务不会尝试使用已从 tabControl 中删除的 tabPage 及其 resultData 进行更新。

下面代码的问题在于它cts是一个对象变量,因此每次我使用新的 CancellationTokenSource 创建一个新选项卡时它都会被覆盖。如果我只需要向 tabControl 添加一个 tabPage,这可能会起作用,但我需要添加很多。

有没有一种方法可以在 searchButton_Click 方法中定义和创建一个取消令牌,并让 tabControl_MouseDown 找到对它的引用,或者有其他方法可以解决这个问题吗?

public class Form1 : Form {

    CancellationTokenSource cts;

    private async void searchButton_Click(object sender, EventArgs e){

        cts = new CancellationTokenSource();

        tabControl1.TabPages.Add(new TabPage());
        var resultData = await Task.Run(() => SlowMethod());
        if (!cts.Token.IsCancellationRequested) { /* add resultData to tabPage */ }

    }

    private void tabControl_MouseDown(object sender, MouseEventArgs e){
        // - I select the tab being hovered with mouse 
        // - I remove the tab from tabControl
        cts.Cancel();
    }
}
4

2 回答 2

2

基于@Steve 答案中找到的提示,我想我找到了一个甜蜜、更简单的解决方案,它不需要使用全局对象来存储 tabPages 及其控件的键值对。

这就是我需要做的一切:

public class Form1 : Form {

    private async void searchButton_Click(object sender, EventArgs e){
        CancellationTokenSource cts = new CancellationTokenSource();
        TabPage myNewTab = new TabPage(); 
        myNewTab.Tag = cts;

        tabControl1.TabPages.Add(myNewTab);
        var resultData = await Task.Run(() => SlowMethod());
        if (!cts.Token.IsCancellationRequested) { /* add resultData to tabPage */ }

    }

    private void tabControl_MouseDown(object sender, MouseEventArgs e){
        // - I select the tab being hovered with mouse 
        // - I remove the tab from tabControl
        CancellationTokenSource cts = (CancellationTokenSource)tabControl1.SelectedTab.Tag;
        cts.Cancel();
    }
}

似乎按预期工作。

于 2016-03-23T01:11:54.097 回答
1

您需要将对象保存在某种全局存储Dictionary<int, CancellationTokenSource>中,例如键是您提供给选项卡的标识符,并且 CancellationTokenSource 与该特定选项卡相关

例如

public class Form1 : Form {
    Dictionary<int, CancellationTokenSource> cts = new Dictionary<int, CancellationTokenSource>();
    int tabID = 0;

    private async void searchButton_Click(object sender, EventArgs e){

        CancellationTokenSource temp = new CancellationTokenSource();

        tabID++;    
        TabPage tp = new TabPage(); 
        tp.Tag = tabID;
        tabControl1.TabPages.Add(tp);

        var resultData = await Task.Run(() => SlowMethod());
        if (!temp.Token.IsCancellationRequested) { /* add resultData to tabPage */ }

       cts.Add(tabID, temp);  
    }

    private void tabControl_MouseDown(object sender, MouseEventArgs e){
        // - I select the tab being hovered with mouse 
        // - I remove the tab from tabControl
        TabPage tp = .... select the tabpage from the mouse position
        CancellationTokenSource temp = cts[Convert.ToInt32(tp.Tag)]
        temp.Cancel();
    }
}

这样,每个单独的 tabPage 都将被唯一标识,并且相应的 CancellationTokenSource 将在字典中键入并在需要时轻松检索。

于 2016-03-22T23:46:56.287 回答