我最近一直在研究Android,并尝试将其中一个函数移植到C#compact framework。
我所做的是创建一个我称之为Activity的Abstract类。 这个类看起来像这个
internal abstract class Activity
{
protected Form myForm;
private static Activity myCurrentActivity = null;
private static Activity myNextActivity = null;
internal static void LoadNext(Activity nextActivity)
{
myNextActivity = nextActivity;
if (myNextActivity != null)
{
myNextActivity.Show();
if (myCurrentActivity != null)
{
myCurrentActivity.Close();
myCurrentActivity = null;
}
myCurrentActivity = myNextActivity;
myNextActivity = null;
}
}
internal void Show()
{
//PROBLEM IS HERE
Application.Run(myForm);
//myForm.Show();
//myForm.ShowDialog();
//
}
internal void Close()
{
myForm.Close();
}
internal void GenerateForm()
{
///Code that uses the Layout class to create a form, and then stores it in myForm
//then attaches click handlers on all the clickable controls in the form
//it is besides the point in this problem
}
protected abstract void Click(Control control);
//this receives all the click events from all the controls in the form
//it is besides the point in this problem
}
我遇到的问题是运行Show()
命令的一部分
基本上我的所有类都实现上面的类,加载一个xml文件并显示它。 当我想转换到新的类/表单时(例如从ACMain转到ACLogIn) 我用这个代码
Activity.LoadNext(new ACLogIn);
应该加载下一个表单,显示它并卸载当前表单
我尝试了这些解决方案(在Show()
方法中),每个问题都存在问题
使用myForm.ShowDialog()
这可以工作,但阻止执行,这意味着旧表单不会关闭,我在表单之间移动越多,进程堆栈增加得越多
使用myForm.Show()
这样可以在显示旧表格后关闭旧表格,但在关闭程序后立即终止它
使用Application.Run(myForm)
这只适用于加载的第一个表单,当我移动到下一个表单时,它显示它然后抛出一个异常,说“值不在预期的范围内”
有人可以帮我解决这个问题或者找个替代方案吗?
答案 0 :(得分:5)
如果你真的在为这个导航创建自己的框架之后,你需要重新思考。传递到Application.Run
的Form实例必须永远不会关闭 - 当它执行时,Application.Run完成执行并且(通常)您的static void Main
入口点退出并且应用程序终止。
我建议您将Activity更改为UserControl:
public abstract class Activity : UserControl
{
....
}
或撰写一个
public abstract class Activity
{
private UserControl m_control;
....
}
然后,不是关闭并显示表单,而是将主表单中的所有活动的父所有作为容器。
作为公平的警告,当你开始想要在Tab主题而不是Stack中显示事物或者具有拆分视图时,这将变得复杂。框架似乎很容易创建,但它们并非如此,我至少考虑使用已经完成的工作,除非你有令人信服的理由想要自己动手。
答案 1 :(得分:1)
Application.Run
通常与带有Form
参数的重载一起使用。这将是负责启动/显示其他表格的“主要”形式。这种“主要”形式可能是“隐藏的”。但是,我认为这有点尴尬。
或者,您不需要主表单,您可以使用Application.Run()
启动消息泵来处理Windows消息;但是,线程正忙于处理消息而无法显示对话框(它们必须显示在运行Application.Run
的线程中)。你可以通过在调用Application.Run
之前创建一个或多个表单对象来解决这个问题,这些表单对象可以创建一个Timer
对象来调用Form.Show()
或{{ 1}}在Form.ShowDialog()
事件处理程序上,以便在调用Timer.Tick
之后显示表单。我认为这也有点尴尬。
这两种解决方案都会绕过你预期使用Windows和WinForms的方式;因此,我认为您需要考虑重新设计此应用程序以使用Windows和.NET的工作方式。