WPF's TabItem's WebBrowser, MVVM的DataTemplate事件绑定
本文关键字:DataTemplate 事件 绑定 WebBrowser TabItem WPF MVVM | 更新日期: 2023-09-27 18:08:27
问题是:如何将WebBrowser的任何事件绑定到ItemTemplate内的视图模型中的ICommand属性?
当我试图使用表达式混合交互库在正常MvvmLight方式做到这一点时,发生异常:
错误收集属性"Microsoft.VisualStudio.DesignTools.WpfDesigner.InstanceBuilders.HwndHostInstance"。"触发"是零。
WebTabItems是项的可观察集合
代码如下:
<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>
选项卡控件中的事件绑定工作得很好,但在模板中不行
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可能是问题是,WebBrowser。导航不是路由事件,但问题是一样的,如何绑定到它的事件?
已经找到了如何在模板中绑定事件的答案,或者当使用Expression混合交互库是不可能的
ICommand类型的附加属性是实现相同功能的另一种方式。
这个答案也可以用于绑定到未路由的事件
在我的例子中:XAML
<WebBrowser Grid.Row="1" Visibility="Visible"
local:WebBrowserExtension.BindableSource="{Binding NavigeteToSourse}"
local:WebBrowserExtension.NavigatingCmdExtended="{Binding NavigatingMVCommand}"
>
</WebBrowser>
分隔类添加附加的依赖属性到原来的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
和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;
}
详细信息请参阅本文:
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 =