C#WinFrom ComboBox SelectedValueChanged事件触发延迟

问题描述

更新:

我还没有找到真正的原因,但是我发现,更新任何其他数据绑定控件的属性都会引发Folder-Combobox中的“ delayed”事件。 到目前为止,这不是一个干净的解决方案,但我通过更新未使用的财产来帮助自己。也就是说,直到我了解真正的原因为止。


原始帖子:

我目前正在研究Windows.Forms项目(不幸的是必须是WinForms),并且我有三个ComboBoxes,每个DataSource都绑定到一个List。列表包含文件夹或文件名。 每个组合框的SelectedItem属性也都绑定到一个字符串。 SelectedValueChanged事件已注册并实现。

它们彼此依赖,所以当我更新combobox1的数据源时,combobox2的数据源也必须更新。这是因为在combobox1中,您可以为文件选择一个子目录,然后在combobox2中列出这些文件。

现在是问题所在。有时会发生,当我以编程方式更新combobox1中的SelectedItem时,SelectedValueChanged事件没有立即触发。程序继续,直到combobox2的数据源更新为止。仅然后,将执行combobox1的SelectedValueChanged事件方法,但不幸的是,它“太迟了”,因为combobox2的数据源已使用combobox1的错误子目录进行了更新。

我想了解,没有立即触发该事件。下面,我发布了相关代码部分的简短示例。

// Cmb1Data and Cmb2Data are the String-Lists which are bound to the DataSource property of the ComboBoxes
// TempCmb1(2)SelectedValue is a string value which contains the value which is to be set.
// Cmb1(2)SelectedValue is a string which is bound the the SelectedItem property of the ComboBoxes

List<string> TempCmb1Data = MainVM.GetCmb1Data();
// some if-statement (plausibility check) is done here before the DataSource is updated.
Cmb1Data = TempCmb1Data ;
if (Cmb1Data.Contains(TempCmb1SelectedValue)
    Cmb1SelectedValue = TempCmb1SelectedValue; // This should fire the event - but sometimes it does not...

List<string> TempCmb2Data = MainVM.GetCmb2Data();
// as before,some if-statement (plausibility check) is done here before the DataSource is updated.
Cmb2Data = TempCmb2Data; // This is the point,where the SelectedValueChangedEvent of Combobox1 suddenly is fired,followed by the SelectdValueChanged event of Combobox 2 

我仔细检查了所有数据绑定和事件方法注册,它们都可以。如果我手动更改SelectedItem,一切也都可以正常运行-只是有时必须以编程方式完成。

先谢谢您。 啊


编辑:

因此,我将代码总结到了相关部分中(如下所述)。当我测试此代码以确保它正确时,没有发生此问题。在我看来,问题隐藏在其他地方,而且不知道在哪里,因此在这里发布的代码太多了。如果发现问题,我将再次深入查看并发布更新。

public partial class Form
{
    RuntimeData _RuntimeData = new RuntimeData();

    private void Form_Load(object sender,EventArgs e)
    {
        AddDataBindings();
    }
    
    private void AddDataBindings()
    {
        cmbFolders.DataBindings.Add("SelectedItem",_RuntimeData,"SelectedFolder");
        cmbFolders.DataBindings.Add("DataSource","Folders");
        cmbFiles.DataBindings.Add("SelectedItem","SelectedFile");
        cmbFiles.DataBindings.Add("DataSource","Files");
    }

    bool _ToggleFlag = false;
    private void btTest_Click(object sender,EventArgs e)
    {
         string TcpString = "Cmd=Execute;Dir=SubDirName1;File=FileName1.dat;";

         if (_ToggleFlag)
             TcpString = "Cmd=Execute;Dir=SubDirName2;File=FileName2.dat;";

         _ToggleFlag = !_ToggleFlag;

         // Method is usually executed in separate thread but the problem exists either way. So Threading removed for simplification
         ParseAndExecute(TcpString,_RuntimeData);
    }

    private void ParseAndExecute(string tcpString,RuntimeData runtimeData)
    {
        if (String.IsNullOrEmpty(tcpString))
            return;

        string[] Elements = tcpString.Split(new char[] { ';','=' },StringSplitOptions.RemoveEmptyEntries);

        // Replaced GetFolders-Method for simplification
        List<string> TempFolders = new List<string>() { "SubDirName1","SubDirName2","SubDirName3" };
        if (TempFolders [0] == Elements[3])
            ;//runtimeData.ProcessFolderChange = true;
        runtimeData.Folders.Clear();
        runtimeData.Folders = TempFolders;
        if (runtimeData.Folders.Contains(Elements[3]))
        {
             if (runtimeData.Folders[0] != Elements[3])
                 ;//runtimeData.ProcessFolderChange = true;
             runtimeData.SelectedFolder = Elements[3];
        }

        // Replaced GetFiles-Method for simplification
        List<string> TempFiles = new List<string>() { "FileName1.dat","FileName2.dat","FileName3.dat" };
        if (TempFiles [0] == Elements[5])
            ;//runtimeData.ProcessFileChange = true;
        runtimeData.Files.Clear();
        runtimeData.Files = TempFiles;
        if (runtimeData.Files.Contains(Elements[5]))
        {
             if (runtimeData.Files[0] != Elements[5])
                 ;//runtimeData.ProcessFileChange = true;
             runtimeData.SelectedFile = Elements[5];
        }
    }

    private void cmbFolders_SelectedValueChanged(object sender,EventArgs e)
    {
        //if (!_RuntimeData.ProcessFolderChange)
            //return;
        //_RuntimeData.ProcessFolderChange = false;

        ((ComboBox)sender).DataBindings["SelectedItem"].WriteValue();

        _RuntimeData.Files.Clear();
        _RuntimeData.Files = new List<string>() { "FileName1.dat","FileName3.dat" };
    }

    private void cmbFiles_SelectedValueChanged(object sender,EventArgs e)
    {
        //if (!_RuntimeData.ProcessFileChange)
            //return;
        //_RuntimeData.ProcessFileChange= false;

        ((ComboBox)sender).DataBindings["SelectedItem"].WriteValue();

        // do some random stuff with the file...
    }
}


// Relevant data from RuntimeData class.
public class RuntimeData : VMBase
{
    private List<string> folders = new List<string>() { "SubDirName1","SubDirName3" };
    public List<string> Folders
    {
        get { return folders; }
        set
        {
            folders = value;            
            OnPropertyChanged(new PropertyChangedEventArgs("Folders"));
        }
    }
    
    private List<string> files = new List<string>()  { "FileName1.dat","FileName3.dat" };
    public List<string> Files
    {
        get { return files; }
        set
        {
            files = value;            
            OnPropertyChanged(new PropertyChangedEventArgs("Files"));
        }
    }

    string selectedFolder = String.Empty;
    public string SelectedFolder
    {
        get { return selectedFolder ; }
        set
        {
            selectedFolder = value;
            OnPropertyChanged(new PropertyChangedEventArgs("SelectedFolder"));
        }
    }

    string selectedFile = String.Empty;
    public string SelectedFile 
    {
        get { return selectedFile ; }
        set
        {
            selectedFile = value;
            OnPropertyChanged(new PropertyChangedEventArgs("SelectedFile"));
        }
    }
}

public abstract class VMBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this,e);
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)