我正在尝试找到一种方法来对表单进行线程安全操作。我创建了一个线程,以在显示表单时更改其位置,并在未显示表单时中止该线程。在我尝试更改位置之前,这一直有效。我尝试使用一种线程安全的方法来更改窗口的位置,但是找不到足够好的方法。
我检查了堆栈溢出情况,但是可能没有在搜索适当的线程。我也用同样的问题搜索过谷歌。
Form1 form;
IntPtr handle = FindWindow(null, WINDOW_NAME);
RECT rect;
Thread posThread;
public FormOverlay(Form1 _form) {
InitializeComponent();
form = _form;
posThread = new Thread(move);
}
private void FormOverlay_Load(object sender, EventArgs e) {
GetWindowRect(handle, out rect);
this.Size = new Size(rect.right - rect.left, rect.bottom - rect.top);
posThread.Start();
}
public struct RECT {
public int left, top, right, bottom;
}
public void move() {
while(form.isChecked()) { // Checkbox in another window
this.Top = rect.top;
this.Left = rect.left;
Thread.Sleep(100);
}
}
我知道
System.InvalidOperationException: 'Cross-thread operation not valid: Control 'FormOverlay' accessed from a thread other than the thread it was created on.
答案 0 :(得分:0)
不要使用循环或线程来解决此问题,Winforms是基于事件的系统,因此请充分利用它。移动表单时将调用事件Move
,您可以在其中放置代码。
您可能还希望订阅CheckedChanged
,并在最初选中该框时也触发移动代码以更新窗口位置。
public FormOverlay(Form1 _form) {
InitializeComponent();
form = _form;
form.SomeCheckbox.CheckedChanged += OnSomeCheckboxChanged
this.Move += OnMove;
}
private void FormOverlay_Load(object sender, EventArgs e) {
GetWindowRect(handle, out rect);
this.Size = new Size(rect.right - rect.left, rect.bottom - rect.top);
}
public struct RECT {
public int left, top, right, bottom;
}
private void OnSomeCheckboxChanged(object sender, System.EventArgs e) {
DoMove();
}
private void OnMove(object sender, System.EventArgs e) {
DoMove();
}
private void DoMove();
if (form.isChecked()) { // Checkbox in another window
this.Top = rect.top;
this.Left = rect.left;
}
}