【问题标题】:Open another view in new task WPF caliburn.micro c#在新任务 WPF caliburn.micro c# 中打开另一个视图
【发布时间】:2013-04-03 08:55:49
【问题描述】:

我在第一个视图(MainView)中有 2 个视图,我选择一个文件并导入它,在第二个视图(BView)中,在数据网格中显示该文件的详细信息。

这是第一个视图(MainView):

这是第二个视图(BView):

我希望当我点击“导入”时出现在进度条和文本上,同时加载第二个视图。我想在另一个 TASK 中打开另一个视图,但收到以下错误消息:

“调用线程无法访问此对象,因为另一个线程拥有它。”

这是MainViewModel的代码是:

[Export(typeof(IShell))]
    public class MainViewModel : Screen
    {
        public string Path{ get; set; }
        public bool IsBusy { get; set; }
        public string Text { get; set; }
        [Import]
        IWindowManager WindowManager { get; set; }

        public MainViewModel()
        {
            IsBusy = false;
            Text = "";
        }


        public void Open()
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "Text|*.txt|All|*.*";
            fd.FilterIndex = 1;

            fd.ShowDialog();

            Path= fd.FileName;
            NotifyOfPropertyChange("Path");
        }


        public void Import()
        {
            if (Percorso != null)
            {
                IsBusy = true;
                Text = "Generate..";
                NotifyOfPropertyChange("IsBusy");
                NotifyOfPropertyChange("Text");
                Task.Factory.StartNew(() => GoNew());

            }
            else
            {
                MessageBox.Show("Select file!", "Error", 
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public void GoNew()
        {
            WindowManager.ShowWindow(new BViewModel(Path), null, null);
            Execute.OnUIThread(() =>
            {
                IsBusy = false;
                NotifyOfPropertyChange("IsBusy");
                Text = "";
                NotifyOfPropertyChange("Text");
            });
        }         

    }

我能做什么?

【问题讨论】:

  • 这可能与WindowManager.ShowWindow 不在 UI 线程上有关吗?看起来其他所有内容都被编组到 UI 线程 - 哪一行会引发错误?
  • 这一行:WindowManager.ShowWindow(new BViewModel(Path), null, null);

标签: c# wpf view caliburn.micro


【解决方案1】:

您需要在 UI 线程上执行 WindowManager.ShowWindow,因为 Task.Start() 将在不同的线程上。任何 UI 操作都应始终编组到 UI 线程,否则会出现您提到的跨线程异常。

试试:

    public void GoNew()
    {
        Execute.OnUIThread(() =>
        {
            WindowManager.ShowWindow(new BViewModel(Path), null, null);
            IsBusy = false;
            NotifyOfPropertyChange("IsBusy");
            Text = "";
            NotifyOfPropertyChange("Text");
        });
    }         

编辑:试试这个

   public void GoNew()
    {
        var vm = new BViewModel(Path);

        Execute.OnUIThread(() =>
        {
            WindowManager.ShowWindow(vm, null, null);
            IsBusy = false;
            NotifyOfPropertyChange("IsBusy");
            Text = "";
            NotifyOfPropertyChange("Text");
        });
    }         

【讨论】:

  • 好的。这行得通 !但是为什么现在进度条是可见的但没有移动呢?
  • 由于您没有发布 B 视图模型代码,我只能假设当您创建此视图模型时,它会做一些工作来导入数据,但您是在 ui 线程中创建您的工作。您需要处理然后显示 vm,而不是在 ui 线程上同时进行
  • 加载 BView 需要 6-7 秒。但是你说我不应该使用 "Execute.OnUIThread(() =>" ??
  • 您需要在显示窗口之前创建视图。创建视图可以在execute.onuithread之外,因为您希望这项工作在任务线程上完成,然后在ui线程中调用show,否则您将锁定ui线程几秒钟
猜你喜欢
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 2011-12-14
  • 2011-06-25
相关资源
最近更新 更多