1
我正在使用CefSharp開發多選項卡瀏覽器。我現在的代碼與CefSharp的github回購中的wpf示例類似。但是,瀏覽器控件無法正常工作。它沒有顯示任何東西。請幫忙。您可以在這裏下載enter link description hereTabControl中的CefSharp不起作用
源的App.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:WpfApplication1.Views"
xmlns:viewModel="clr-namespace:WpfApplication1.ViewModels"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type viewModel:BrowserTabViewModel}">
<view:BrowserTabView />
</DataTemplate>
</Application.Resources>
</Application>
App.xaml.cs
using System.Windows;
namespace WpfApplication1
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
CefSharp.Cef.Initialize(new CefSharp.CefSettings());
base.OnStartup(e);
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WpfApplication1.Controls"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Google" Command="New" CommandParameter="http://google.com"></MenuItem>
</Menu>
<controls:NonReloadingTabControl
x:Name="TabControl"
Margin="0,5,0,0"
ItemsSource="{Binding BrowserTabs, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="0">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
<Button Content="X"
Height="20"
Width="20"
FontFamily="Courier"
FontWeight="Bold"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Command="Close"
FontSize="10"
Padding="0"
Margin="10,0,0,0"
ToolTip="Close"/>
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</controls:NonReloadingTabControl>
</DockPanel>
</Window>
個
MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using WpfApplication1.ViewModels;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<BrowserTabViewModel> BrowserTabs { get; set; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
BrowserTabs = new ObservableCollection<BrowserTabViewModel>();
CommandBindings.Add(new CommandBinding(ApplicationCommands.New, OpenNewTab));
CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, CloseTab));
}
private void CloseTab(object sender, ExecutedRoutedEventArgs e)
{
if (BrowserTabs.Count > 0)
{
//Obtain the original source element for this event
var originalSource = (FrameworkElement)e.OriginalSource;
BrowserTabViewModel browserViewModel = null;
if (originalSource is MainWindow)
{
browserViewModel = BrowserTabs[TabControl.SelectedIndex];
BrowserTabs.RemoveAt(TabControl.SelectedIndex);
}
else
{
//Remove the matching DataContext from the BrowserTabs collection
browserViewModel = (BrowserTabViewModel)originalSource.DataContext;
BrowserTabs.Remove(browserViewModel);
}
browserViewModel.WebBrowser.Dispose();
}
}
private void OpenNewTab(object sender, ExecutedRoutedEventArgs e)
{
CreateNewTab((string)e.Parameter);
TabControl.SelectedIndex = TabControl.Items.Count - 1;
}
private void CreateNewTab(string url = "about:blank")
{
BrowserTabs.Add(new BrowserTabViewModel(url));
}
}
}
BroswerTabView.xaml
<UserControl x:Class="WpfApplication1.Views.BrowserTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<ProgressBar
HorizontalAlignment="Right"
IsIndeterminate="{Binding WebBrowser.IsLoading}"
Width="100"
Height="16"
Margin="3" />
</StatusBar>
<cefSharp:ChromiumWebBrowser
Address="{Binding Address, Mode=TwoWay}"
Title="{Binding Title, Mode=OneWayToSource}"
WebBrowser="{Binding WebBrowser, Mode=OneWayToSource}" />
</DockPanel>
</UserControl>
BrowserTabView.xaml.cs
using System.Windows.Controls;
namespace WpfApplication1.Views
{
/// <summary>
/// Interaction logic for BrowserTabView.xaml
/// </summary>
public partial class BrowserTabView : UserControl
{
public BrowserTabView()
{
InitializeComponent();
}
}
}
BrowserTabViewModel.cs個
using CefSharp.Wpf;
using GalaSoft.MvvmLight;
namespace WpfApplication1.ViewModels
{
public class BrowserTabViewModel : ViewModelBase
{
private string address;
public string Address
{
get { return address; }
set { Set(ref address, value); }
}
private string title;
public string Title
{
get { return title; }
set { Set(ref title, value); }
}
private IWpfWebBrowser webBrowser;
public IWpfWebBrowser WebBrowser
{
get { return webBrowser; }
set { Set(ref webBrowser, value); }
}
public BrowserTabViewModel(string address)
{
Address = address;
}
}
}
NonReloadingTabControl.cs
using System;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace WpfApplication1.Controls
{
[TemplatePart(Name = "PART_ItemsHolder", Type = typeof(Panel))]
public class NonReloadingTabControl : TabControl
{
private Panel itemsHolderPanel;
public NonReloadingTabControl()
{
// This is necessary so that we get the initial databound selected item
ItemContainerGenerator.StatusChanged += ItemContainerGeneratorStatusChanged;
}
/// <summary>
/// If containers are done, generate the selected item
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ItemContainerGeneratorStatusChanged(object sender, EventArgs e)
{
if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
ItemContainerGenerator.StatusChanged -= ItemContainerGeneratorStatusChanged;
UpdateSelectedItem();
}
}
/// <summary>
/// Get the ItemsHolder and generate any children
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
itemsHolderPanel = GetTemplateChild("PART_ItemsHolder") as Panel;
UpdateSelectedItem();
}
/// <summary>
/// When the items change we remove any generated panel children and add any new ones as necessary
/// </summary>
/// <param name="e"></param>
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (itemsHolderPanel == null)
return;
switch (e.Action)
{
case NotifyCollectionChangedAction.Reset:
itemsHolderPanel.Children.Clear();
break;
case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Remove:
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
var cp = FindChildContentPresenter(item);
if (cp != null)
itemsHolderPanel.Children.Remove(cp);
}
}
// Don't do anything with new items because we don't want to
// create visuals that aren't being shown
UpdateSelectedItem();
break;
case NotifyCollectionChangedAction.Replace:
throw new NotImplementedException("Replace not implemented yet");
}
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
UpdateSelectedItem();
}
private void UpdateSelectedItem()
{
if (itemsHolderPanel == null)
return;
// Generate a ContentPresenter if necessary
var item = GetSelectedTabItem();
if (item != null)
CreateChildContentPresenter(item);
// show the right child
foreach (ContentPresenter child in itemsHolderPanel.Children)
child.Visibility = ((child.Tag as TabItem).IsSelected) ? Visibility.Visible : Visibility.Collapsed;
}
private ContentPresenter CreateChildContentPresenter(object item)
{
if (item == null)
return null;
var cp = FindChildContentPresenter(item);
if (cp != null)
return cp;
var tabItem = item as TabItem;
cp = new ContentPresenter
{
Content = (tabItem != null) ? tabItem.Content : item,
ContentTemplate = this.SelectedContentTemplate,
ContentTemplateSelector = this.SelectedContentTemplateSelector,
ContentStringFormat = this.SelectedContentStringFormat,
Visibility = Visibility.Collapsed,
Tag = tabItem ?? (this.ItemContainerGenerator.ContainerFromItem(item))
};
itemsHolderPanel.Children.Add(cp);
return cp;
}
private ContentPresenter FindChildContentPresenter(object data)
{
if (data is TabItem)
data = (data as TabItem).Content;
if (data == null)
return null;
if (itemsHolderPanel == null)
return null;
foreach (ContentPresenter cp in itemsHolderPanel.Children)
{
if (cp.Content == data)
return cp;
}
return null;
}
protected TabItem GetSelectedTabItem()
{
var selectedItem = SelectedItem;
if (selectedItem == null)
return null;
var item = selectedItem as TabItem ?? ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as TabItem;
return item;
}
}
}
嘗試將文件內容複製到示例項目文件的頂部,並使用git比較不同之處分配辦法。 – amaitland