Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CefSharp.Avalonia.Example/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CefSharp.Avalonia.Example.App">
<Application.Styles>
<FluentTheme/>
</Application.Styles>
</Application>
35 changes: 35 additions & 0 deletions CefSharp.Avalonia.Example/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using CefSharp.Avalonia.Example.ViewModels;
using CefSharp.Avalonia.Example.Views;
using ReactiveUI;
using Splat;

namespace CefSharp.Avalonia.Example;

public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);

Locator.CurrentMutable.Register(() => new BrowserView(), typeof(IViewFor<BrowserViewModel>));
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var mainWindow = new MainWindow();

desktop.MainWindow = mainWindow;
desktop.ShutdownRequested += (s, e) =>
{
mainWindow.Dispose();
};
}

base.OnFrameworkInitializationCompleted();
}
}
29 changes: 29 additions & 0 deletions CefSharp.Avalonia.Example/CefSharp.Avalonia.Example.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>CefSharp.Avalonia.Example</AssemblyName>
<RootNamespace>CefSharp.Avalonia.Example</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.0-preview5" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview5" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.0-preview5" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview5" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview5" />
<PackageReference Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup>

<ItemGroup>
<TrimmerRootDescriptor Include="Roots.xml" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CefSharp.Avalonia\CefSharp.Avalonia.csproj" />
</ItemGroup>

</Project>

56 changes: 56 additions & 0 deletions CefSharp.Avalonia.Example/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:rxui="using:Avalonia.ReactiveUI"
x:Class="CefSharp.Avalonia.Example.MainWindow"
MinWidth="500"
MinHeight="300"
Title="CefSharp.Avalonia.Example">
<Window.Styles>
<Style Selector="TabControl">
<Setter Property="Background" Value="#F0F0F0"/>
</Style>

<Style Selector="TabControl WrapPanel">
<Setter Property="Background" Value="#2B579A"/>
</Style>

<Style Selector="TabItem">
<Setter Property="FontSize" Value="16"/>
<Setter Property="Height" Value="34"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Background" Value="#2B579A"/>
<Setter Property="Foreground" Value="#F0F0F0"/>
</Style>
<Style Selector="TabItem:pointerover">
<Setter Property="Background" Value="#124078"/>
</Style>

<Style Selector="TabItem:selected">
<Setter Property="Background" Value="#f0f0f0"/>
<Setter Property="Foreground" Value="#2B579A"/>
</Style>
</Window.Styles>

<Grid RowDefinitions="Auto, *">
<Menu Name="mainMenu" Grid.Row="0">
<MenuItem Header="_File">
<MenuItem Header="_New Tab" Command="{Binding AddTab}" />
<Separator/>
<MenuItem Header="_Exit" Click="OnFileExitMenuItemClick"/>
</MenuItem>
</Menu>

<TabControl Name="tabControl" Grid.Row="1" Items="{Binding Tabs}" AutoScrollToSelectedItem="True">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<rxui:ViewModelViewHost ViewModel="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
55 changes: 55 additions & 0 deletions CefSharp.Avalonia.Example/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Interactivity;
using CefSharp.Avalonia.Example.ViewModels;
using CefSharp.Avalonia.Example.Views;
using CefSharp.OutOfProcess;
using System;
using System.IO;
using System.Threading.Tasks;

namespace CefSharp.Avalonia.Example;

public partial class MainWindow : Window, IDisposable
{
#if DEBUG
private string _buildType = "Debug";
#else
private string _buildType = "Release";
#endif

private OutOfProcessHost _outOfProcessHost;

public MainWindow()
{
InitializeComponent();

_ = InitializeComponentAsync();
}

private async Task InitializeComponentAsync()
{
var outOfProcessHostPath = Path.GetFullPath($"..\\..\\..\\..\\CefSharp.OutOfProcess.BrowserProcess\\bin\\{_buildType}");
outOfProcessHostPath = Path.Combine(outOfProcessHostPath, OutOfProcessHost.HostExeName);
var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\OutOfProcessCache");

var settings = Settings.WithCachePath(cachePath);
_outOfProcessHost = await OutOfProcessHost.CreateAsync(outOfProcessHostPath, settings);

ChromiumWebBrowser.SetDefaultOutOfProcessHost(_outOfProcessHost);

DataContext = new MainWindowViewModel();
}

private BrowserView ActiveBrowserView => (BrowserView) this.FindControl<TabControl>("tabControl").SelectedContent;

private void OnFileExitMenuItemClick(object sender, RoutedEventArgs e)
{
Close();
}

public void Dispose()
{
_outOfProcessHost?.Dispose();
}
}
22 changes: 22 additions & 0 deletions CefSharp.Avalonia.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Avalonia;
using Avalonia.ReactiveUI;
using System;

namespace CefSharp.Avalonia.Example;

public static class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);

// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseReactiveUI()
.UsePlatformDetect()
.LogToTrace();
}
5 changes: 5 additions & 0 deletions CefSharp.Avalonia.Example/Roots.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<linker>
<!-- Can be removed if CompiledBinding and no reflection are used -->
<assembly fullname="CefSharp.Avalonia.Example" preserve="All" />
<assembly fullname="Avalonia.Themes.Fluent" preserve="All" />
</linker>
17 changes: 17 additions & 0 deletions CefSharp.Avalonia.Example/ViewModels/BrowserViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ReactiveUI;
using System.Runtime.Serialization;

namespace CefSharp.Avalonia.Example.ViewModels
{
public class BrowserViewModel : ViewModelBase
{
private string _header;

[DataMember]
public string Header
{
get => _header;
set => this.RaiseAndSetIfChanged(ref _header, value);
}
}
}
19 changes: 19 additions & 0 deletions CefSharp.Avalonia.Example/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.ObjectModel;

namespace CefSharp.Avalonia.Example.ViewModels
{
internal class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<BrowserViewModel> Tabs { get; } = new();

public MainWindowViewModel()
{
AddTab();
}

public void AddTab()
{
Tabs.Add(new BrowserViewModel { Header = "New Tab" });
}
}
}
22 changes: 22 additions & 0 deletions CefSharp.Avalonia.Example/ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using ReactiveUI;
using System.Reactive.Disposables;

namespace CefSharp.Avalonia.Example.ViewModels
{
public class ViewModelBase : ReactiveObject, IActivatableViewModel
{
public ViewModelActivator Activator { get; }

public ViewModelBase()
{
Activator = new ViewModelActivator();
this.WhenActivated((CompositeDisposable disposables) =>
{
/* handle activation */
Disposable
.Create(() => { /* handle deactivation */ })
.DisposeWith(disposables);
});
}
}
}
15 changes: 15 additions & 0 deletions CefSharp.Avalonia.Example/Views/BrowserView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cefSharp="using:CefSharp.Avalonia"
xmlns:vm="using:CefSharp.Avalonia.Example.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:BrowserViewModel"
x:Class="CefSharp.Avalonia.Example.Views.BrowserView">

<DockPanel>
<TextBox x:Name="addressTextBox" DockPanel.Dock="Top" KeyDown="OnAddressTextBoxKeyDown" />
<cefSharp:ChromiumWebBrowser x:Name="Browser"/>
</DockPanel>
</UserControl>
60 changes: 60 additions & 0 deletions CefSharp.Avalonia.Example/Views/BrowserView.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Threading;
using CefSharp.Avalonia.Example.ViewModels;
using CefSharp.OutOfProcess;
using ReactiveUI;
using Tmds.DBus;

namespace CefSharp.Avalonia.Example.Views;

public partial class BrowserView : UserControl, IViewFor<BrowserViewModel>
{
public BrowserView()
{
InitializeComponent();

Browser.Address = "https://www.google.com";
Browser.AddressChanged += OnAddressChanged;
Browser.TitleChanged += OnTitleChanged;
}

public BrowserViewModel? ViewModel { get; set; }

object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (BrowserViewModel?)value;
}

private void OnTitleChanged(object sender, TitleChangedEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
ViewModel.Header = e.Title;
});
}

private void OnAddressChanged(object sender, AddressChangedEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
var addressTextBox = this.FindControl<TextBox>("addressTextBox");

addressTextBox.Text = e.Address;
});
}

private void OnAddressTextBoxKeyDown(object sender, global::Avalonia.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
Browser.Address = ((TextBox)sender).Text;
}
}

public void Dispose()
{
//browser.Dispose();
}
}
Loading