将列表框绑定到索引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(用于不跨线程)
是否有一种方法可以通过myfor/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();
}