线程调用主窗口? [英] Thread invoke the main window?

查看:96
本文介绍了线程调用主窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以基本上我有一个MainWindow,一个在单独的cs文件中定义的类SetupViewModel,另一个在单独的cs文件中定义的类ImageViewModel. 我想知道是否可以从ImageViewModel调用MainWindow中的操作.下面列出了更多详细信息:

So basically I have a MainWindow, a class SetupViewModel defined in a separate cs file, and another class ImageViewModel in a separate cs file; I am wondering is there anyway I can invoke the operation in MainWindow from ImageViewModel. More details listed below:

  • 在ImageViewModel中,按如下所示在MainWindow中调用更改(以下代码在MainWindow中):

this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                new Action(
                    delegate()
                    {
                            ((SetupViewModel)this.DataContext).ViewType = Convert.ToInt32(ViewTypes.ViewType2D);
                    }
                )
            );

  • SetupViewModel中定义的ViewType变量如下

  • The ViewType variable is defined in SetupViewModel as follows

    private int _viewType;
        public int ViewType
        {
            get
            {
                return _viewType;
            }
            set
            {
                _viewType = value;
                OnPropertyChanged("ViewType");
            }
        }
    

  • 这是我的工作方式,但没有成功; ImageViewModel中的调用代码:

  • Here is how I did, but was not successful; The invoke code in ImageViewModel:

    尝试 { 动作SwitchTo2DView =委托() { ((CaptureSetupViewModel)System.Windows.Application.Current.MainWindow.DataContext).ViewType = Convert.ToInt32(ViewTypes.ViewType2D); };

    try { Action SwitchTo2DView = delegate() { ((CaptureSetupViewModel)System.Windows.Application.Current.MainWindow.DataContext).ViewType = Convert.ToInt32(ViewTypes.ViewType2D); };

                System.Windows.Application.Current.MainWindow.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, SwitchTo2DView);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught exception: " + ex.ToString());
            }
    

  • 和例外情况:

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
       at CaptureSetupDll.ViewModel.LiveImageViewModel.<StartZStackPreview>b__2c()
       --- End of inner exception stack trace ---
       at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Delegate.DynamicInvokeImpl(Object[] args)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method)
       at CaptureSetupDll.ViewModel.LiveImageViewModel.StartZStackPreview()
    

    我是C#的外行;知道我该如何进行这项工作吗?非常感谢.

    I am a layman to C#; Any idea how I can make this work? Thanks a lot.

    推荐答案

    我打赌你要花5美元,在调用DataContext时,您的DataContext为null.这意味着它可能被称为为时过早.这可能意味着您应该将您正在执行的所有操作推到Dispatcher上.

    I'll bet you five bucks your DataContext is null at the time this is being called. Which means its probably being called too early. Which probably means you should push whatever you're doing off on the Dispatcher.

    尽管您可以假设在调用此方法时完全加载了应用程序,但不一定是正确的.要对此进行测试,请在调试过程中设置一个断点,然后检查DataContext是否为空.

    While you may assume your application is completely loaded at the time this method is being called, it isn't necessarily true. To test this, set a breakpoint during debugging and check the DataContext to see if it's null.

    如果为空,则有两个选择.首先,只需返回即可.根据调用方法的方式,在加载过程中可能会多次调用该方法.稍后的调用可能会显示一个非空的上下文.

    If it is null, you have two choices. First, just return. Depending on how the method is being called, it may be called multiple times during load. A later call may reveal a non-null context.

    另一种选择是使用 Dispatcher 加载应用程序后,稍后再调用该方法.

    The other option is to use the Dispatcher to re-call the method later, once the application is loaded.

    这里有一些伪代码,看起来像C#,甚至可以编译:

    Here's a little pseudocode which looks kind of like C# and may even compile:

    public void CheckTheDataContext()
    {
        // is it null?
        if(this.DataContext == null)
        {
            // then drop an Action re-invoking this method later
            // when the application idles out a bit
            Dispatcher.BeginInvoke((Action)(() =>
            {
                CheckTheDataContext();
            }), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
            return;
        }
        DoSomethingElseWithTheContext(DataContext);
    }
    

    这篇关于线程调用主窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆