использование CefSharp WPF с MVVM

Я использую элемент управления CefSharp WPF в проекте с MVVM Light. Я пытаюсь показать ProgessRing, когда браузер загружает новую страницу. Итак, я привязываю две команды к подходящим событиям и получаю сообщение об ошибке. Это моя вина или проблема CefSharp или MVVM? См. следующий код.

 <wpf:ChromiumWebBrowser 
        Address="{Binding Url, Mode=OneWay}" 
        x:Name="cwbDescription"
        Grid.Row="0" 
        Grid.RowSpan="14" 
        Grid.Column="3"
        ZoomLevel="{Binding BrowserZoom, Mode=OneWay}"
        Visibility="{Binding IsReadOnly, Converter={StaticResource BoolToVis}, FallbackValue=Hidden}"
        Tag="{Binding}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <command:EventToCommand Command="{Binding BrowserLoadedCommand, Mode=TwoWay}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="FrameLoadStart">
                <command:EventToCommand Command="{Binding FrameLoadStartCommand}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="FrameLoadEnd">
                <command:EventToCommand Command="{Binding FrameLoadEndCommand}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </wpf:ChromiumWebBrowser> 

    <controls:ProgressRing IsActive="{Binding IsDownloadInProgress}" IsLarge="True" Grid.Column="3" Grid.Row="0" Grid.RowSpan="14" />

...

    private ICommand _frameLoadStartCommand;
    private ICommand _frameLoadEndCommand;
...

    public ICommand FrameLoadStartCommand
    {
        get { return this._frameLoadStartCommand; }
        set { Set(() => FrameLoadStartCommand, ref this._frameLoadStartCommand, value); }
    }

    public ICommand FrameLoadEndCommand
    {
        get { return this._frameLoadEndCommand; }
        set { Set(() => FrameLoadEndCommand, ref this._frameLoadEndCommand, value); }
    }
...
    FrameLoadStartCommand = new RelayCommand<FrameLoadStartEventArgs>(FrameLoadStart, x => true);
    FrameLoadEndCommand = new RelayCommand<FrameLoadEndEventArgs>(FrameLoadEnd, x => true);

...
    private void FrameLoadStart(FrameLoadStartEventArgs args)
    {
        IsDownloadInProgress = true;
    }

    private void FrameLoadEnd(FrameLoadEndEventArgs args)
    {
        IsDownloadInProgress = false;
    }

И в результате я получаю эту ошибку

2016-06-14 10:53:32.303 HomeCinema.ApplicationOne.MainWindow2::current domain unhandled exception object: System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
   at System.Windows.Interactivity.TriggerBase.get_Actions()
   at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
   at CefSharp.Wpf.ChromiumWebBrowser.CefSharp.Internals.IWebBrowserInternal.OnFrameLoadStart(FrameLoadStartEventArgs args)
   at CefSharp.Internals.ClientAdapter.OnLoadStart(ClientAdapter* , CefRefPtr<CefBrowser>* browser, CefRefPtr<CefFrame>* frame) 
 exception: System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
   at System.Windows.Interactivity.TriggerBase.get_Actions()
   at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
   at CefSharp.Wpf.ChromiumWebBrowser.CefSharp.Internals.IWebBrowserInternal.OnFrameLoadStart(FrameLoadStartEventArgs args)
   at CefSharp.Internals.ClientAdapter.OnLoadStart(ClientAdapter* , CefRefPtr<CefBrowser>* browser, CefRefPtr<CefFrame>* frame) 
 stack trace;    at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
   at System.Windows.Interactivity.TriggerBase.get_Actions()
   at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
   at CefSharp.Wpf.ChromiumWebBrowser.CefSharp.Internals.IWebBrowserInternal.OnFrameLoadStart(FrameLoadStartEventArgs args)
   at CefSharp.Internals.ClientAdapter.OnLoadStart(ClientAdapter* , CefRefPtr<CefBrowser>* browser, CefRefPtr<CefFrame>* frame)

person Anton    schedule 14.06.2016    source источник
comment
Эти события вызываются в другом потоке как исключение. ChromiumWebBriwser уже имеет довольно много DependencyProperties, в вашем случае просто привяжите к IsLoading github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf/   -  person amaitland    schedule 14.06.2016
comment
github.com/cefsharp/CefSharp. MinimalExample/blob/master/ показывает другой метод использования свойств в привязках. В качестве общего замечания, проект CefSharp.Wpf.Example действительно использует пакет MvvmLightLibs, это не пример модели MVVM, хотя многое из этого должно дать вам идеи о том, как работать с проектом. Я бы предложил написать несколько пользовательских IValueConverter.   -  person amaitland    schedule 14.06.2016
comment
Спасибо вам за совет. Я привязал ProgressRing к свойству зависимости IsLoading, и это помогло.   -  person Anton    schedule 14.06.2016
comment
Большой. Если вы новичок в WPF и многопоточности, я бы посоветовал вам немного почитать справочную информацию, что-то вроде msdn.microsoft.com/en-us/magazine/dn630646.aspx может помочь.   -  person amaitland    schedule 14.06.2016
comment
вы можете обратиться к моему ответу на этот пост ожидание загрузки cefsharp   -  person Yash Soni    schedule 20.11.2018