It's a bit hum to have a user control open a form, consider raising an event so that the control's parent form stays in control and displays the dialog.
But okay if the dialog is a complete implementation detail of the control. Don't set the Parent, you need to use the ShowDialog(owner) overload if you want to pick a specific owner. It isn't typically necessary, the ShowDialog() method goes hunting for a suitable owner if you don't specify one. You can find the parent form of the control back with code like this:
private Form GetParentForm() {
var parent = this.Parent;
while (!(parent is Form)) parent = parent.Parent;
return parent as Form;
}
But you've got another problem, also the reason why you asked this question in the first place. Your dialog right now doesn't have an owner and it is likely to disappear behind another window. That's because your code runs on another thread. A thread that created no windows, and thus can't supply an owner window, and the reason for the cross-thread exception message.
You need to use Control.Invoke to run the dialog code on the UI thread. There's a good example of it in the MSDN Library topic for it.