繁体   English   中英

WPF:dispatcher.invoke不运行

[英]WPF: dispatcher.invoke do not running

我编写了我的第一个WPF应用程序,其中包括几页:

  1. 带有徽标的欢迎页面
  2. 带有登录表单的登录页面
  3. 带有帐户信息的主页

MainWindow包含<Frame> WPF控件,并且我使用动画来显示下一页/上一页。

我编写自己的MainAnimation类来执行动画。

该应用程序可以在我的笔记本电脑上正常工作,但是当我尝试在朋友动画的计算机上运行它时,什么也不做。

我认为与相关麻烦Dispatcher.Invoke()方法调用,而我试图找到解决方案通过网络( 这里 这里 这里这里 ),我尝试:

  • 使用Application.Current.Dispatcher
  • 使用Dispatcher.BeginInvoke()代替Dispatcher.Invoke()

但它什么也没做。

因此,我仅显示“欢迎”页面2秒钟,并且“登录”页面必须自动加载。

这是WelcomePage.xaml.cs文件的代码:

public partial class WelcomePage : Page {
    public WelcomePage (MainWindow parent) {
        InitializeComponent();
        this.parent = parent;

        Task.Factory.StartNew(() => ShowLoginForm());
    }

    private MainWindow parent;

    private void ShowLoginForm()
    {
        Thread.Sleep(2000);
        this.parent.GoToLoginForm();
    }

}

这是MainWindow.xaml.cs文件的代码:

public partial class MainWindow : Window {
    public MainWindow () {
        InitializeComponent();

        animation = new MainAnimation(this, this, Main, new WelcomePage(this));
    }

    private MainAnimation animation;

    public void GoToLoginForm() => animation.ShowNextPage(new LoginPage(this));
    public void GoToVideosForm() => animation.ShowNextPage(new MainPage(this));

}

这是MainAnimation类( MainAnimation.cs )的相关部分:

public class MainAnimation 
{
    public MainAnimation(FrameworkElement resourcesOwner, DispatcherObject dispatcherOwner, Frame currentPageContainer, Page firstPage)
    {
        this.resourcesOwner = resourcesOwner;
        this.dispatcherOwner = dispatcherOwner;
        this.currentPageContainer = currentPageContainer;

        pages = new Stack<Page>();
        pages.Push(firstPage);

        currentPageContainer.Content = pages.Peek();
    }

    private Stack<Page> pages;
    private FrameworkElement resourcesOwner;
    private DispatcherObject dispatcherOwner;
    private Frame currentPageContainer;

    private void ShowPageForward()
    {
        dispatcherOwner.Dispatcher.Invoke((Action)delegate {
            if (currentPageContainer.Content != null)
            {
                var page = currentPageContainer.Content as Page;
                if (page != null)
                {
                    page.Loaded -= NextPage_Loaded;
                    UnloadPageForward(page);
                }
            }
            else
            {
                LoadPageForward();
            }
        });
    }

    private void UnloadPageForward(Page page)
    {
        Storyboard sb = (resourcesOwner.FindResource("SlideForwardOut") as Storyboard).Clone();
        sb.Completed += StoryboardForward_Completed;
        sb.Begin(currentPageContainer);
    }

    private void StoryboardForward_Completed(object sender, EventArgs e)
    {
        LoadPageForward();
    }

    private void LoadPageForward()
    {
        pages.Peek().Loaded += NextPage_Loaded;
        currentPageContainer.Content = pages.Peek();
    }

    private void NextPage_Loaded(object sender, RoutedEventArgs e)
    {
        Storyboard sb = resourcesOwner.FindResource("SlideForwardIn") as Storyboard;
        sb.Begin(currentPageContainer);
    }

}

我是WPF的新手,可能只是不了解一些细节,因此,如果您能帮助我解决这个很小但很令人反感的问题,我将非常高兴。

更新#1:软件版本

  • 开发操作系统:Windows 10 x64
  • 测试操作系统:Windows 8.1 x64
  • VS版本:Visual Studio 2017社区版
  • 应用目标框架:v.4.5

由于WPF控件具有线程相似性,因此在大多数情况下,在后台线程上创建它们没有多大意义。

如果要在显示登录页面之前等待2秒钟,则可以使用DispatcherTimer或异步等待:

public partial class WelcomePage : Page
{
    public WelcomePage(MainWindow parent)
    {
        InitializeComponent();
        this.parent = parent;

        ShowLoginForm();
    }

    private MainWindow parent;

    private async void ShowLoginForm()
    {
        await Task.Delay(2000);
        this.parent.GoToLoginForm();
    }
}

然后,您将不需要对Dispatcher.Invoke任何调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM