Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将列表框绑定到索引C#_C#_Winforms_Data Binding_Listbox - Fatal编程技术网

将列表框绑定到索引C#

将列表框绑定到索引C#,c#,winforms,data-binding,listbox,C#,Winforms,Data Binding,Listbox,我不知道这是否可能,但我想要的是这样的东西 在WinFormlistbox1中有一个行列表(从文件中复制) 在另一个线程和类中,我在一个列表上运行,该列表包含我解析的每一行和DoSomething 完成该行后,我希望列表框中的索引发生更改 从我基本的和有限的理解来看,我的方法是使用事件以形式触发,而不是使用Invoke(用于不跨线程) 是否有一种方法可以通过myfor/foreach循环以某种方式绑定到listbox的索引 class form { listBoxScript.SetSe

我不知道这是否可能,但我想要的是这样的东西 在
WinForm
listbox1
中有一个行列表(从文件中复制)

在另一个线程和类中,我在一个列表上运行,该列表包含我解析的每一行和
DoSomething
完成该行后,我希望列表框中的索引发生更改

从我基本的和有限的理解来看,我的方法是使用
事件
以形式触发,而不是使用Invoke(用于不跨线程)

是否有一种方法可以通过my
for/foreach
循环以某种方式绑定到
listbox
的索引

class form
{
    listBoxScript.SetSelected(ScriptCounter, true);<--bind the ScriptCounter?
}

确保在
RunScript
类中实现
INotifyPropertyChanged
。以下是完整的示例:

class RunScript : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int scriptCounter;

    private ISynchronizeInvoke invoker;
    public RunScript(ISynchronizeInvoke invoker)
    {
        if (invoker == null) throw new ArgumentNullException("invoker");
        this.invoker = invoker;
    }

    public async void RunScriptList()
    {
        ScriptCounter = 0;
        foreach (var cell in Enumerable.Range(1, 15))
        {
            ScriptCounter++;
            await Task.Delay(1000);
            //DoSomething
        }
    }

    public int ScriptCounter
    {
        get { return scriptCounter; }
        set
        {
            scriptCounter = value;
            OnPropertyChanged();
        }
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            Action action = () => handler(this, new PropertyChangedEventArgs(propertyName));
            invoker.Invoke(action, null);
        }
    }
}

private RunScript rs;
public Form1()
{
    InitializeComponent();

    rs = new RunScript(this)

    var binding = new Binding("SelectedIndex", rs, "ScriptCounter", false, DataSourceUpdateMode.OnPropertyChanged);
    listBox1.DataBindings.Add(binding);
}

private void button1_Click(object sender, EventArgs e)
{
    rs.RunScriptList();
}

注意:我在
RunScriptList
中使用了
async/await
,如果在另一个线程中使用,则需要在主线程中触发
PropertyChanged
事件,以避免跨线程异常。

以某种方式将列表框的索引绑定到我的for/foreach循环是什么意思?循环与绑定有什么关系?发布一些代码会有所帮助。我将添加一些代码,使其更加清晰,并提及哪种技术。Winforms还是WPF?我想是的winforms@SriramSakthivelDone==WinForm非常感谢!若我使用Invoke在主线程(窗体运行的地方)中激发OnPropertyChanged,那个么就可以了吗?或者我需要用一个事件来完成它?是的,在
OnPropertyChanged
内部调用是可以的,或者你可以使用
Send
Post
方法恐怕我对“SynchronizationContext”来说太深了,要求你发布如何实现调用会太多吗?我将在几分钟后将其标记为一个答案更新我的代码以使用
Invoke
,您需要将
ISynchronizeInvoke
传递到
RunScript
类,如果
ISynchronizeInvoke
对您来说是新的,请不要害怕
Form
实现该接口。严格来说,您可以通过任何
控制。而且。。。不客气:)遗憾的是,我得到“无法绑定到目标控件上的属性'ScriptListBox'。在放置代码时。。。
class RunScript : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int scriptCounter;

    private ISynchronizeInvoke invoker;
    public RunScript(ISynchronizeInvoke invoker)
    {
        if (invoker == null) throw new ArgumentNullException("invoker");
        this.invoker = invoker;
    }

    public async void RunScriptList()
    {
        ScriptCounter = 0;
        foreach (var cell in Enumerable.Range(1, 15))
        {
            ScriptCounter++;
            await Task.Delay(1000);
            //DoSomething
        }
    }

    public int ScriptCounter
    {
        get { return scriptCounter; }
        set
        {
            scriptCounter = value;
            OnPropertyChanged();
        }
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            Action action = () => handler(this, new PropertyChangedEventArgs(propertyName));
            invoker.Invoke(action, null);
        }
    }
}

private RunScript rs;
public Form1()
{
    InitializeComponent();

    rs = new RunScript(this)

    var binding = new Binding("SelectedIndex", rs, "ScriptCounter", false, DataSourceUpdateMode.OnPropertyChanged);
    listBox1.DataBindings.Add(binding);
}

private void button1_Click(object sender, EventArgs e)
{
    rs.RunScriptList();
}