2016-04-01 19 views
1

WPF WebBrowser denetimini uygulayan bir uygulamam var. Uygulamamdan, muhtemelen diğer iş parçacıklarından çağrılması gereken bazı JS işlevlerini içeren bir sayfa yükler. Tercihen, MVVM modeline yapışmak ve modelde fonksiyon dönüşünü ayrıştırmak için kodu tutmak istiyorum. WebBrowser nesnesindeki InvokeScript yönteminin çağrılması, bir UI öğesi olduğundan, Dispatcher iş parçacığında (ve dolayısıyla görünümde) gerçekleşmelidir.Dağıtıcı olmadan WPF web tarayıcısında Javascript'i çağırın

Şu anda bu işi yapmak için izleyeceğiniz adımlar (kabaca pseudo) 'dir:

- subscribe to the LoadCompleted event of the browser (view) 
- set the browser source (model -> viewmodel -> view) 
- catch the LoadCompleted event (view -> viewmodel -> model) 
- some logic (model) 
- invoke script (model -> viewmodel -> view) 
- get script result (view -> viewmodel -> model) 
- some logic (model) 

Bu (ViewModel aracılığıyla) modeli ve görünümü arasında oldukça uzun bir sırt ve ileri-iletişim sonuçlanır . WPF (veya bu konudaki MVVM) ile deneyimlediğimden beri, bu görevi yerine getirmenin daha iyi bir yolunun olup olmadığını merak ediyorum (ve neat: demek istediğim: model, viewmodel ve görünüm arasındaki daha az çağrı ve olay).

cevap

0

Bu sorunun tam olarak yanıtı olmadığını biliyorum, ancak gelecekte daha da size yardımcı olabilir. CefSharp adlı bileşene bir göz atın. Bu, Chrome Gömülü Çerçeve'nin etrafında bir C# sarıcıdır. Çok MVVM dostudur, açık kaynak kodlu, ücretsiz ve geliştirmek için oldukça kolaydır. Kısa bir süre önce başka bir Chrome sarıcısından (Awesomium) taşındım ve bununla çok mutluyum.

CefSharp, sayfadan js işlevlerini çağırmanıza ve hatta bu çağrılar için eşzamanlı/beklemeyi desteklemenize olanak tanır.

+0

güzel öneri That. Ancak, CefSharp'ın Awasomium ya da WPF WebBrowser ile karşılaştırıldığında gerçek avantajları nedir? – Bart

+0

Awesomium'un avantajı, CefSharp'ın açık kaynak kodlu ve ücretsiz olmasıdır. Awesomium için destek çok eksik. Büyük ve ciddi bir şirket olduklarına inanmanızı istiyorlar, ama gerçek şu ki - sadece bir adam. Kod açık olmadığından, hataları düzeltmek için geliştiricinin merhametine sahipsiniz. Ve proje ÇOK yavaş hareket ediyor. Sanırım hala krom 16 gibi bir şey kullanıyorlar. –

+0

Yerel WPF WebBrowser kontrolü söz konusu olduğunda, bununla ilgili çok fazla deneyimim olmadığını itiraf ediyorum. Başından beri üçüncü taraf kontrollerinin yoluna gittik. Ama akla gelen bazı şeyler var. Örneğin, CefSharp'ın MVVM modeli ile çok fazla akılda tutulması gibi. Hemen hemen her şey bir Komut veya DependencyProperty. Ayrıca tarayıcı ile çok fazla etkileşim async/await patter üzerinden yapılır. Bu da yerel WPF kontrolü üzerinde olumlu bir şeydir. –

0

MVVM'nin ana noktası, farklı platformlardaki mantığı (viewmodel \ model) yeniden kullanabilmeniz için, arabirimi (platform özel: windows \ android \ ios \ windows phone vb.) Birbirinden ayırmaktır. Bu nedenle, InvokeScript'i doğrudan viewmodel'den çağıramazsınız - ancak dağıtıcıdan dolayı değil. Dispatcher (for example) 'ı soyutlayabilirsiniz, çünkü bazı durumlarda görünüm modelinizde buna ihtiyacınız vardır.

public class MyViewModel 
{ 
    public Func<string, object> InvokeScript { get; set; } 
    public Func<string, Task<object>> InvokeScriptAsync { get; set; } 

    public async void Something() { 
     var result = await InvokeScriptAsync("my script"); 
     // do something 
    } 
} 

Ve görünümünde: - Yani genellikle ViewModel görünümde işlemi gerçekleştirmek için gerektiğinde olayları (veya sadece delege) kullanılır

public class MyView { 
    private void OnViewModelChanged(MyViewModel vm) { 
     vm.InvokeScript = text => Dispatcher.Invoke(() => browser.InvokeScript(text)); 
     vm.InvokeScriptAsync = text => browser.InvokeScriptAsync(text); // for example 
    } 
} 
+0

Evet, tamamen anlıyorum. Gerçekleştirmeye çalıştığım şey, gerçekten (görünüm) modelden görünümü ayırmaktır. Öyleyse söylediğiniz şey, sadece görüşme yapmak için viewmodel'den haber almak için olayları (veya delegeleri) kullanmalı mıyım? – Bart

+0

Evet ve gerekmedikçe (ör. ObservableCollection kullandığınızda) vm'de dağıtıcı ile uğraşmayın. Genellikle çoğu mantık (iş mantığı hariç) modelde değil, modelde de bulunur, bu nedenle modelden görünümüne çok sayıda etkileşim olmamalıdır. – Evk