如何使用Prism MVVM连接Awesomium WebControl事件

时间:2014-05-07 01:46:40

标签: wpf xaml mvvm awesomium

我继承了一个使用Prism MVVM的WPF MVVM项目。我想在视图上使用Awesomium WebControl。我在xaml中定义了WebControl,如下所示:

<awe:WebControl Name="taskBrowser" Source="http://localhost:59298/Tasks" Height="680" Width="680">

这很好用,但我还需要能够将数据从网页中的Javascript事件传递到WPF应用程序。当我在代码隐藏中执行此操作时,我有这个工作,但由于我们使用MVVM,我想以“正确”方式执行操作,并且不知道如何在后面的代码中执行,而是在ViewModel中。问题1是:我需要在ViewModel中连接DocumentReady事件,如下所示。

问题2是:我需要对ViewModel中的taskBrowser进行一些引用,以便能够执行如下所示的“taskBrowser.CreateGlobalJavascriptObject”命令,将网页js连接到WPF方法。但是在ViewModel un-MVVM中引用了taskBrowser对象?我怎么能通过这个参考?无论如何,谁能告诉我如何处理这两个问题?

public MyCodeBehindConstructor()
{
    {
        InitializeComponent();
        ...
        taskBrowser.DocumentReady += TaskBrowserOnDocumentReady;
    }
}

private void TaskBrowserOnDocumentReady(object sender, UrlEventArgs urlEventArgs)
{
    taskBrowser.DocumentReady -= TaskBrowserOnDocumentReady;
    JSObject jsobject = taskBrowser.CreateGlobalJavascriptObject("jsobject");
    jsobject.Bind("callNETNoReturn", false, JSHandler);
}

private void JSHandler(object sender, JavascriptMethodEventArgs args)
{
    if (args.MustReturnValue)
    {
        Console.WriteLine("Got method call with return request");
        args.Result = "Returning " + args.Arguments[0];
    }
    else
    {
        Console.WriteLine("Got method call with no return request");
    }
}

1 个答案:

答案 0 :(得分:2)

我刚刚发布了一个新的框架,可以在C#ViewModel和awesomium之间进行所有管道工作。 基本上,您需要一次调用将viewmodel链接到IWebView,然后框架将创建将反映C#视图模型的javascripts对象。 它基于knouckout.js,所以它是完整的MVVM。 ICommand也映射到javascript方法,您可以使用knouckout标记绑定。通过INotityPropertyChanged和INotityCollectionChanged跟踪更改的集合和属性。 您可以在github上找到包含示例的整个项目:https://github.com/David-Desmaisons/MVVM-for-awesomium 例如:查看模型:

public class ViewModelBase : INotifyPropertyChanged
    {
        protected void Set<T>(ref T ipnv, T value, string ipn)
        {
            if (object.Equals(ipnv, value))
                return;
            ipnv = value;
            OnPropertyChanged(ipn);
        }

        protected virtual void OnPropertyChanged(string pn)
        {
            if (PropertyChanged == null)
                return;

            PropertyChanged(this, new PropertyChangedEventArgs(pn));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

   public class Person: ViewModelBase
    {
        public Person()
        {
            Skills = new ObservableCollection<Skill>();
            RemoveSkill = new RelayCommand<Skill>(s=> this.Skills.Remove(s));
        }

        private string _LastName;
        public string LastName
        {
            get { return _LastName; }
            set { Set(ref _LastName, value, "LastName"); }
        }

        private string _Name;
        public string Name
        {
            get { return _Name; }
            set { Set(ref _Name, value, "Name"); }
        }

        public IList<Skill> Skills { get; private set; }

        public ICommand RemoveSkill { get; private set; }
    } 

查看(HTML +淘汰赛加价):

<!doctype html>
<html>
    <head>
        <title></title>
        <script src="js/knockout.js" type="text/javascript"></script>
        <script src="js/Ko_Extension.js" type="text/javascript"></script>
    </head>
    <body>
        <input type="text" data-bind="value: Name, valueUpdate:'afterkeydown'" placeholder="First name" >
        <ul data-bind="foreach: Skills">
            <li><span data-bind="text:Type"></span>:<span data-bind="text:Name"></span>
            <button data-bind="click: function (){$root.RemoveSkill($data)}">Remove skill</button></li>
        </ul>
        <div>
            <h2><span data-bind="text: Name"></span></h2>
            <h2><span data-bind="text: LastName"></span></h2>
        </div>

        <button data-bind="click: ChangeSkill">Click me</button>
    </body>
</html>

结合:

IWebView mywebview = ...; //retrieve awesomium view wich loaded the HTML view
var datacontext = new Person();
AwesomeBinding.Bind(mywebview, datacontext, JavascriptBindingMode.TwoWay);