WPF程序 当关闭一个窗体后,重新打开报错 关闭窗口之后无法设置 Visibility 或者调用 Show或ShowDialog

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF程序 当关闭一个窗体后,重新打开报错 关闭窗口之后无法设置 Visibility 或者调用 Show或ShowDialog相关的知识,希望对你有一定的参考价值。

解决这个问题了。。。不用重写子窗口的closing中 this.Hide();
我在类class1中写:
public static Window1 tempWindow = new Window1();
public static void winnn()
Window1 tempWindow = new Window1();
在主窗体的click事件中写
Class1.tempWindow.Owner = this.Window;
Class1.winnn();
Class1.tempWindow.cc();
在window1中写一个函数:
public void cc()
this.Window.Show();
这样每次关闭子窗口window1后再点击主窗口的click事件打开window1 就不会报错了。

这很简单呀。在主页后台设置一个属性bool型的就成。你打开窗体后,如果默认是false,你设置为true。如果是ture么,你就在打开窗体的时候ShowDialog报打开错误的指示框。追问

这个可能是字数限制问题可能没表述清楚,不好意思是这样的:程序中我在按钮click事件用ShowDialog打开了一个window1,然后当我关闭这个窗体后,重新按按钮想打开这个窗体时 ,报错。错误:关闭窗口之后无法设置 Visibility 或者调用 Show或ShowDialog。请问这是为什么呢。我的办法就是在closing写了this.Hide();暂时解决了。但是不明白原因。请赐教。

追答

我想应该是当你关闭一个窗体的时候,窗体实例就没回收了,或是在前台区域就没有加载了。所以无法设置 Visibility 或者调用 Show或ShowDialog。

追问

每次重新写个 new 实例 就可以了么?

追答

恩,这个可行!~

参考技术A 在关闭事件里写this.Hide();追问

暂时 这样解决了 ,可是这是为什么能 想知道原因,请赐教。

关闭和重新打开应用程序后,Android 画布游戏循环中断 onResume()

【中文标题】关闭和重新打开应用程序后,Android 画布游戏循环中断 onResume()【英文标题】:Android canvas game loop breaks onResume() after closing and reopening app 【发布时间】:2015-08-03 04:03:21 【问题描述】:

在全新安装时,当我第一次打开应用程序时,我真的没有任何问题。但是,如果我要通过进程终止应用程序、强制停止或简单地按下主页按钮并重新启动应用程序,我会遇到一些问题......

第一个问题 - 当应用程序在关闭或终止后重新启动时,在实际启动应用程序窗口之前有很长的延迟。此外,有时需要 30 秒才能显示游戏图形(绘制到画布上的内容)。当我听到游戏音效在后台播放时,我看到的只是黑屏,就好像它正在运行一样。

第二个问题 - 在等待应用程序实际显示画布大约 30 秒后,有时 on touch 侦听器会被取消注册等。我无法与游戏互动,就好像我的触摸没有注册一样。再一次,这只发生在应用程序成功运行一次然后关闭/终止后的 RELAUNCH 上。

第三个问题 - 如果我不耐烦并且不等待画布显示的 30 秒,而是点击主页按钮或终止“无响应”应用程序,我总是会得到一条错误消息说“应用程序无响应,等待?强制关闭?”或“意外错误,应用程序已停止运行。”

所以这些问题让我相信这是我如何开始/重新启动/创建游戏循环的问题:

public class MainMenuActivity extends ActionBarActivity implements View.OnTouchListener


MenuView menu;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    menu = new MenuView(this);
    menu.setOnTouchListener(this);
    setContentView(R.layout.activity_main_menu);

    Button buttonplay = (Button)findViewById(R.id.buttonPlay);
    buttonplay.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            launchCanvas();
        
    );


public void launchCanvas()
     setContentView(menu)



@Override
public boolean onTouch(View v, MotionEvent event) 
         ////do stuff
    
    return true;



////////////////////////////////////////inner MenuView class

public class MenuView extends SurfaceView implements Runnable 

    Thread t = null;
    SurfaceHolder holder;
    boolean ok;
    Game game;

    public MenuView(Context context)
        super(context);
        game = new Game(this);
        holder = getHolder();
    

    @SuppressLint("WrongCall")
    @Override
    public void run() 
        while(ok)
            if(!holder.getSurface().isValid())
                continue;
            

            Canvas c = holder.lockCanvas();
            onDraw(c);
            holder.unlockCanvasAndPost(c);
        
    


    public void onDraw(Canvas canvas)
        canvas.drawARGB(255, 1, 5, 29);
        game.draw(canvas);
    

    public void pause()
        ok = false;
        while(true)
            try
                t.join();
            catch (InterruptedException e)
                e.printStackTrace();
            
            break;
        
        t=null;
    
    public void resume()
        ok = true;
        t = new Thread(this);
        t.start();
    



    
////////////////////////////////////////////////////end MenuView class`



@Override
protected void onPause() 
    super.onPause();
    menu.pause();


@Override
protected void onResume() 
    super.onResume();
    menu.resume();

关于如何解决的任何想法?

更新 - 发现潜在问题 我相信我的问题的根源在于不让我的线程休眠。我在线程循环的每次迭代调用的 draw() 方法中添加了以下 try 块:

try 
    Thread.sleep(10);
 catch (InterruptedException e) 
    e.printStackTrace();

虽然现在有点波折不平,但我无法重现上述问题。

我刚刚从 10 毫秒更改为仅睡眠 1 毫秒,它不再波涛汹涌,仍然无法重现问题。 1ms 似乎是微不足道的......为什么线程睡眠微不足道的时间是必要的?

【问题讨论】:

线程睡眠可以节省电池并让处理器得到一些休息......除此之外我真的想不出任何东西...... 【参考方案1】:

我自己的基于 SurfaceView 的应用程序有一个单独的线程,其中运行两个方法:update() 和 draw()。但是,draw() 方法仅在canvas != null 时运行。这是我与暂停和恢复相关的所有代码,除了有一个运行此代码的surfaceCreated(SurfaceHolder sh) ...

if(!thread.isAlive()) 
    thread.setRunning(true);
    thread.start();

如果这对你没有帮助,我的整个框架中的相关部分:

Main.java

将 MainView 设置为内容视图 (setContentView(mainView))

MainView.java

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) 
    Log.d(TAG, "Surface created");
    tf = Typeface.create("Roboto", Typeface.BOLD);
    recalc=true;
    if(!thread.isAlive()) 
        thread.setRunning(true);
        thread.start();
    

MainThread.java

public class MainThread extends Thread 
    // (abridged) Game logic loop
    @Override
    public void run() 
        Canvas canvas;
        Log.d(TAG, "Starting game loop");
        while (running) 
            canvas = null;
            // try locking the canvas for exclusive pixel editing
            // in the surface
            try 
                canvas = this.surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) 
                    // update game state
                    mainView.update();
                    // render state to the screen
                    if (canvas != null) mainView.render(canvas); // canvas == null when activity is in background.
                    // ... my code then handles sleeping, etc. for fixed fps.
                
             finally 
            // in case of an exception the surface is not left in
            // an inconsistent state
            if (canvas != null) 
                surfaceHolder.unlockCanvasAndPost(canvas);
            
        
    

希望这对您有意义!您应该能够根据需要将其调整到您自己的项目中。

【讨论】:

我添加了一个surfaceDestroyed 和surfaceCreated 覆盖。还是有加载时间问题,还有onTouchListener不工作的问题 我想我找到了我的问题.. 更新了问题。将不胜感激任何进一步的反馈。谢谢。【参考方案2】:

请记住,SurfaceView 有两个部分,Surface 和 View。如果您在 SurfaceView 子类中覆盖 onDraw(),您将同时执行这两种操作,并且您在 View 上绘制的任何内容都会掩盖您在 Surface 上绘制的内容。 (Surface 是一个独立的层,默认情况下位于 View UI 层之后。)

我通常建议不要对 SurfaceView 进行子类化,因为这样做没有任何价值,而且会产生奇怪的可能性。 SurfaceView Surface 是您绘制的东西,而不是您需要专门研究其行为的对象。 (与custom View 对比。)

您可能想阅读有关暂停/恢复/线程逻辑的 SurfaceView and Activity lifecycle interaction 和有关如何最好地构建游戏渲染的一些想法 game loops。具体示例指向Grafika。

添加睡眠调用会影响竞态条件。如果您的应用没有比赛,则无需休眠。 (而且,正如游戏循环文章中所说,它们不是管理帧速率的好方法。)

小点:ok应该标记为volatile,否则run()中允许编译器忽略。

【讨论】:

以上是关于WPF程序 当关闭一个窗体后,重新打开报错 关闭窗口之后无法设置 Visibility 或者调用 Show或ShowDialog的主要内容,如果未能解决你的问题,请参考以下文章

C#实现一个弹窗监控小程序

wpf 一个窗体中点击空白部分关闭另一个窗体

款式修改窗口,开发调整过窗口格局保存功能,关了窗口重新打开还是按关闭前的格局.

C# WPF: 在一个窗体上设置一个按钮,点击这个按钮时,打开新窗体并关闭原窗体?

新手求教WPF中如何设置打开子窗体后父窗体关闭或隐藏.

wpf 主界面写个重新登录按钮,点击按钮之后登录界面打开,主界面关闭如何实现。