简体   繁体   English

WPF的TabItem的WebBrowser、MVVM的DataTemplate中的事件绑定

[英]Binding of event in DataTemplate of WPF's TabItem's WebBrowser, MVVM

Question is: How to bind any event of WebBrowser to ICommand property in my View Model inside of ItemTemplate?问题是:如何将 WebBrowser 的任何事件绑定到 ItemTemplate 内我的视图模型中的 ICommand 属性?

When i am trying to do this using the Expression blend interactivity libraries in normal for MvvmLight way, an exeption ocurs:当我尝试使用表达式混合交互库以正常的 MvvmLight 方式执行此操作时,会出现异常:

Error Collection property 'Microsoft.VisualStudio.DesignTools.WpfDesigner.InstanceBuilders.HwndHostInstance'.'Triggers' is null.错误集合属性 'Microsoft.VisualStudio.DesignTools.WpfDesigner.InstanceBuilders.HwndHostInstance'.'Triggers' 为空。

WebTabItems is observable collection of items ViewModels WebTabItems 是可观察的项目 ViewModels 集合

Here is code:这是代码:

 <TabControl  ItemsSource="{Binding WebTabItems}" SelectedItem="{Binding SelectedWebTabItem}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <mvvm:EventToCommand Command="{Binding SelectionChangedVMCommand}" PassEventArgsToCommand="True"></mvvm:EventToCommand>
                    </i:EventTrigger>
                </i:Interaction.Triggers>

                <TabControl.ItemTemplate>
                    <!--header-->
                    <DataTemplate>
                        <TextBlock Text="{Binding Header}"></TextBlock>                            
                    </DataTemplate>                        
                </TabControl.ItemTemplate>
                <TabControl.ContentTemplate>
                    <DataTemplate>                        
                        <Grid >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto"></RowDefinition>
                                <RowDefinition></RowDefinition>
                            </Grid.RowDefinitions>

                            <TextBlock Text="{Binding NotificationRibbonText}" Visibility="{Binding NotificationRibbonVisibility}"></TextBlock>


                            <WebBrowser Grid.Row="1" Visibility="Visible" local:WebBrowserExtension.BindableSource="{Binding Sourse}" >
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="Navigating">
                                        <mvvm:EventToCommand Command="{Binding NavigatingMVCommand}" PassEventArgsToCommand="True" ></mvvm:EventToCommand>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </WebBrowser>



                        </Grid>
                    </DataTemplate>
                </TabControl.ContentTemplate>

            </TabControl>

Event binding in tab control works great but in template does not选项卡控件中的事件绑定效果很好,但在模板中不行

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
                                   <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="Navigating">
                                            <mvvm:EventToCommand Command="{Binding NavigatingMVCommand}" PassEventArgsToCommand="True" ></mvvm:EventToCommand>
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>

Ps May be the problem is that WebBrowser.Navigating is not routed event, but problem is the same, How to bind to it event? Ps 可能问题是WebBrowser.Navigating 不是路由事件,但问题是一样的,如何绑定到它的事件?

Have foud an answer how to bind event in template or when using Expression blend interactivity libraries is impossible有答案如何在模板中绑定事件或何时使用表达式混合交互库是不可能的

Attached property of ICommand type is other way through which you can achieve the same functionality. ICommand 类型的附加属性是您可以实现相同功能的另一种方式。

This answer can also be used for binding to not Routed events此答案也可用于绑定到非路由事件

In my case: XAML就我而言:XAML

  <WebBrowser Grid.Row="1" Visibility="Visible" 
                                        local:WebBrowserExtension.BindableSource="{Binding NavigeteToSourse}" 
                                        local:WebBrowserExtension.NavigatingCmdExtended="{Binding NavigatingMVCommand}" 

                                        >

                            </WebBrowser>

separated class to add attached dependency properties to original web browser将附加依赖属性添加到原始 Web 浏览器的分离类

 class WebBrowserExtension
    {

    #region BindableSourceProperty

    public static readonly DependencyProperty BindableSourceProperty =
    DependencyProperty.RegisterAttached("BindableSource", typeof(string), typeof(WebBrowserExtension), new UIPropertyMetadata("", BindableSourcePropertyChanged));

    public static string GetBindableSource(DependencyObject obj)
    {
        return (string)obj.GetValue(BindableSourceProperty);
    }

    public static void SetBindableSource(DependencyObject obj, string value)
    {
        obj.SetValue(BindableSourceProperty, value);
    }

    public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        WebBrowser browser = o as WebBrowser;
        if (browser != null)
        {
            string uri = e.NewValue as string;
            browser.Source = !String.IsNullOrEmpty(uri) ? new Uri(uri) : null;
        }
    }
    #endregion

        #region NavigatingCmdExtended

        public static ICommand GetNavigatingCmdExtended(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(NavigatingCmdExtendedProperty);
        }
        public static void SetNavigatingCmdExtended(DependencyObject obj, ICommand value)
        {
            obj.SetValue(NavigatingCmdExtendedProperty, value);
        }
        // Using a DependencyProperty as the backing store for CalenderOpenCommand. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NavigatingCmdExtendedProperty =
        DependencyProperty.RegisterAttached("NavigatingCmdExtended", typeof(ICommand), typeof(WebBrowserExtension), new PropertyMetadata(OnChangedNavigatingCmdExtendedProperty));


        private static void OnChangedNavigatingCmdExtendedProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var webBrowser = d as WebBrowser;
            if (webBrowser != null)
            {
                if (e.NewValue != null)
                {
                    //attach event handler
                    webBrowser.Navigating += webBrowser_Navigating;
                }
                else
                {
                    //detach event handler
                    webBrowser.Navigating -= webBrowser_Navigating;
                }
            }
        }
        ///
        /// Event handler for Calender Opened event.
        ///
        ///
        ///
        static void webBrowser_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            ICommand command = GetNavigatingCmdExtended(sender as DependencyObject);
            if (command != null)
            {
                if (command.CanExecute(e))
                {
                    //executes a command
                    command.Execute(e);
                }
            }
        }
        #endregion

and command in ViewModel和 ViewModel 中的命令

public class WebTabItemVievModel: ViewModelBase
{

    public WebTabItemVievModel()
    {

        NavigatingMVCommand = new RelayCommand<NavigatingCancelEventArgs>(NavigatingMethod);

    }



    public ICommand NavigatingMVCommand { get;  set; }
    private void NavigatingMethod(NavigatingCancelEventArgs e)
    {
        Messenger.Default.Send<NotificationMessage <UriChangedMSG>>(new NotificationMessage<UriChangedMSG> (new UriChangedMSG { NewUri = e.Uri.AbsoluteUri },"test"));
        CurrentUri = e.Uri.AbsoluteUri;
        NotificationRibbonText = e.Uri.AbsoluteUri;
    }

Refer this article for details:详情请参考这篇文章:

http://www.codeproblem.com/articles/frameworks/wpf/87-event-to-command-binding-using-attached-properties-in-plain-wpf-without-any-extra-dependancy?showall=1&limitstart= http://www.codeproblem.com/articles/frameworks/wpf/87-event-to-command-binding-using-attached-properties-in-plain-wpf-without-any-extra-dependancy?showall=1&limitstart=

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM