7 changed files with 1 additions and 371 deletions
@ -1,31 +0,0 @@ |
|||
<Window x:Class="WindowsInteropTest.EmbedToWpfDemo" |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:av="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:avalonia="clr-namespace:Avalonia.Win32.Interoperability;assembly=Avalonia.Win32.Interoperability" |
|||
mc:Ignorable="d" |
|||
d:DesignHeight="400" d:DesignWidth="400" MinWidth="500" MinHeight="400"> |
|||
<DockPanel> |
|||
<GroupBox DockPanel.Dock="Left" Header="WPF"> |
|||
<StackPanel> |
|||
<Slider/> |
|||
<Calendar/> |
|||
</StackPanel> |
|||
</GroupBox> |
|||
<GroupBox Header="Avalonia button" DockPanel.Dock="Bottom"> |
|||
<avalonia:WpfAvaloniaHost> |
|||
<av:Button Content="Avalonia button"/> |
|||
</avalonia:WpfAvaloniaHost> |
|||
</GroupBox> |
|||
<GroupBox Header="AvBtn" DockPanel.Dock="Right"> |
|||
<avalonia:WpfAvaloniaHost x:Name="RightBtn"> |
|||
<av:Button Content="Avalonia button 2"/> |
|||
</avalonia:WpfAvaloniaHost> |
|||
</GroupBox> |
|||
<GroupBox Header="Avalonia"> |
|||
<avalonia:WpfAvaloniaHost x:Name="Host"/> |
|||
</GroupBox> |
|||
</DockPanel> |
|||
</Window> |
|||
@ -1,29 +0,0 @@ |
|||
using System.Windows; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using ControlCatalog; |
|||
|
|||
namespace WindowsInteropTest |
|||
{ |
|||
public partial class EmbedToWpfDemo |
|||
{ |
|||
public EmbedToWpfDemo() |
|||
{ |
|||
InitializeComponent(); |
|||
Host.Content = new MainView(); |
|||
|
|||
var btn = (Button) RightBtn.Content!; |
|||
btn.Click += delegate |
|||
{ |
|||
btn.Content += "!"; |
|||
}; |
|||
|
|||
Loaded += OnLoaded; |
|||
} |
|||
|
|||
private void OnLoaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
TopLevel.GetTopLevel((MainView)Host.Content)!.AttachDevTools(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
namespace WindowsInteropTest |
|||
{ |
|||
partial class SelectorForm |
|||
{ |
|||
/// <summary>
|
|||
/// Required designer variable.
|
|||
/// </summary>
|
|||
private System.ComponentModel.IContainer components = null; |
|||
|
|||
/// <summary>
|
|||
/// Clean up any resources being used.
|
|||
/// </summary>
|
|||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|||
protected override void Dispose(bool disposing) |
|||
{ |
|||
if (disposing && (components != null)) |
|||
{ |
|||
components.Dispose(); |
|||
} |
|||
base.Dispose(disposing); |
|||
} |
|||
|
|||
#region Windows Form Designer generated code
|
|||
|
|||
/// <summary>
|
|||
/// Required method for Designer support - do not modify
|
|||
/// the contents of this method with the code editor.
|
|||
/// </summary>
|
|||
private void InitializeComponent() |
|||
{ |
|||
this.btnEmbedToWinForms = new System.Windows.Forms.Button(); |
|||
this.btnEmbedToWpf = new System.Windows.Forms.Button(); |
|||
this.SuspendLayout(); |
|||
//
|
|||
// btnEmbedToWinForms
|
|||
//
|
|||
this.btnEmbedToWinForms.Location = new System.Drawing.Point(12, 12); |
|||
this.btnEmbedToWinForms.Name = "btnEmbedToWinForms"; |
|||
this.btnEmbedToWinForms.Size = new System.Drawing.Size(201, 86); |
|||
this.btnEmbedToWinForms.TabIndex = 0; |
|||
this.btnEmbedToWinForms.Text = "Embed to WinForms"; |
|||
this.btnEmbedToWinForms.UseVisualStyleBackColor = true; |
|||
this.btnEmbedToWinForms.Click += new System.EventHandler(this.btnEmbedToWinForms_Click); |
|||
//
|
|||
// btnEmbedToWpf
|
|||
//
|
|||
this.btnEmbedToWpf.Location = new System.Drawing.Point(219, 12); |
|||
this.btnEmbedToWpf.Name = "btnEmbedToWpf"; |
|||
this.btnEmbedToWpf.Size = new System.Drawing.Size(201, 86); |
|||
this.btnEmbedToWpf.TabIndex = 1; |
|||
this.btnEmbedToWpf.Text = "Embed to WPF"; |
|||
this.btnEmbedToWpf.UseVisualStyleBackColor = true; |
|||
this.btnEmbedToWpf.Click += new System.EventHandler(this.btnEmbedToWpf_Click); |
|||
//
|
|||
// SelectorForm
|
|||
//
|
|||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); |
|||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; |
|||
this.ClientSize = new System.Drawing.Size(432, 284); |
|||
this.Controls.Add(this.btnEmbedToWpf); |
|||
this.Controls.Add(this.btnEmbedToWinForms); |
|||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; |
|||
this.MaximizeBox = false; |
|||
this.Name = "SelectorForm"; |
|||
this.Text = "Interop"; |
|||
this.ResumeLayout(false); |
|||
|
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
private System.Windows.Forms.Button btnEmbedToWinForms; |
|||
private System.Windows.Forms.Button btnEmbedToWpf; |
|||
} |
|||
} |
|||
|
|||
@ -1,30 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
using System.Data; |
|||
using System.Drawing; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using System.Windows.Forms; |
|||
|
|||
namespace WindowsInteropTest |
|||
{ |
|||
public partial class SelectorForm : Form |
|||
{ |
|||
public SelectorForm() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
|
|||
private void btnEmbedToWinForms_Click(object sender, EventArgs e) |
|||
{ |
|||
new EmbedToWinFormsDemo().ShowDialog(this); |
|||
} |
|||
|
|||
private void btnEmbedToWpf_Click(object sender, EventArgs e) |
|||
{ |
|||
new EmbedToWpfDemo().ShowDialog(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,120 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<root> |
|||
<!-- |
|||
Microsoft ResX Schema |
|||
|
|||
Version 2.0 |
|||
|
|||
The primary goals of this format is to allow a simple XML format |
|||
that is mostly human readable. The generation and parsing of the |
|||
various data types are done through the TypeConverter classes |
|||
associated with the data types. |
|||
|
|||
Example: |
|||
|
|||
... ado.net/XML headers & schema ... |
|||
<resheader name="resmimetype">text/microsoft-resx</resheader> |
|||
<resheader name="version">2.0</resheader> |
|||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
|||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
|||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
|||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
|||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
|||
<value>[base64 mime encoded serialized .NET Framework object]</value> |
|||
</data> |
|||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
|||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
|||
<comment>This is a comment</comment> |
|||
</data> |
|||
|
|||
There are any number of "resheader" rows that contain simple |
|||
name/value pairs. |
|||
|
|||
Each data row contains a name, and value. The row also contains a |
|||
type or mimetype. Type corresponds to a .NET class that support |
|||
text/value conversion through the TypeConverter architecture. |
|||
Classes that don't support this are serialized and stored with the |
|||
mimetype set. |
|||
|
|||
The mimetype is used for serialized objects, and tells the |
|||
ResXResourceReader how to depersist the object. This is currently not |
|||
extensible. For a given mimetype the value must be set accordingly: |
|||
|
|||
Note - application/x-microsoft.net.object.binary.base64 is the format |
|||
that the ResXResourceWriter will generate, however the reader can |
|||
read any of the formats listed below. |
|||
|
|||
mimetype: application/x-microsoft.net.object.binary.base64 |
|||
value : The object must be serialized with |
|||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
|||
: and then encoded with base64 encoding. |
|||
|
|||
mimetype: application/x-microsoft.net.object.soap.base64 |
|||
value : The object must be serialized with |
|||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
|||
: and then encoded with base64 encoding. |
|||
|
|||
mimetype: application/x-microsoft.net.object.bytearray.base64 |
|||
value : The object must be serialized into a byte array |
|||
: using a System.ComponentModel.TypeConverter |
|||
: and then encoded with base64 encoding. |
|||
--> |
|||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
|||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
|||
<xsd:element name="root" msdata:IsDataSet="true"> |
|||
<xsd:complexType> |
|||
<xsd:choice maxOccurs="unbounded"> |
|||
<xsd:element name="metadata"> |
|||
<xsd:complexType> |
|||
<xsd:sequence> |
|||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
|||
</xsd:sequence> |
|||
<xsd:attribute name="name" use="required" type="xsd:string" /> |
|||
<xsd:attribute name="type" type="xsd:string" /> |
|||
<xsd:attribute name="mimetype" type="xsd:string" /> |
|||
<xsd:attribute ref="xml:space" /> |
|||
</xsd:complexType> |
|||
</xsd:element> |
|||
<xsd:element name="assembly"> |
|||
<xsd:complexType> |
|||
<xsd:attribute name="alias" type="xsd:string" /> |
|||
<xsd:attribute name="name" type="xsd:string" /> |
|||
</xsd:complexType> |
|||
</xsd:element> |
|||
<xsd:element name="data"> |
|||
<xsd:complexType> |
|||
<xsd:sequence> |
|||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
|||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
|||
</xsd:sequence> |
|||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
|||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
|||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
|||
<xsd:attribute ref="xml:space" /> |
|||
</xsd:complexType> |
|||
</xsd:element> |
|||
<xsd:element name="resheader"> |
|||
<xsd:complexType> |
|||
<xsd:sequence> |
|||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
|||
</xsd:sequence> |
|||
<xsd:attribute name="name" type="xsd:string" use="required" /> |
|||
</xsd:complexType> |
|||
</xsd:element> |
|||
</xsd:choice> |
|||
</xsd:complexType> |
|||
</xsd:element> |
|||
</xsd:schema> |
|||
<resheader name="resmimetype"> |
|||
<value>text/microsoft-resx</value> |
|||
</resheader> |
|||
<resheader name="version"> |
|||
<value>2.0</value> |
|||
</resheader> |
|||
<resheader name="reader"> |
|||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
|||
</resheader> |
|||
<resheader name="writer"> |
|||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
|||
</resheader> |
|||
</root> |
|||
@ -1,84 +0,0 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using System.Windows; |
|||
using System.Windows.Interop; |
|||
using System.Windows.Markup; |
|||
using Avalonia.Controls.Embedding; |
|||
using Avalonia.Win32.Interop; |
|||
using AvControl = Avalonia.Controls.Control; |
|||
|
|||
namespace Avalonia.Win32.Interoperability; |
|||
|
|||
/// <summary>
|
|||
/// An element that allows you to host a Avalonia control on a WPF page.
|
|||
/// </summary>
|
|||
[ContentProperty("Content")] |
|||
public class WpfAvaloniaHost : HwndHost |
|||
{ |
|||
private EmbeddableControlRoot? _root; |
|||
private AvControl? _content; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="WpfAvaloniaHost"/> class.
|
|||
/// </summary>
|
|||
public WpfAvaloniaHost() |
|||
{ |
|||
DataContextChanged += AvaloniaHwndHost_DataContextChanged; |
|||
} |
|||
|
|||
private void AvaloniaHwndHost_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e) |
|||
{ |
|||
if (Content != null) |
|||
{ |
|||
Content.DataContext = e.NewValue; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the Avalonia control hosted by the <see cref="WpfAvaloniaHost"/> element.
|
|||
/// </summary>
|
|||
public AvControl? Content |
|||
{ |
|||
get => _content; |
|||
set |
|||
{ |
|||
if (_content != value) |
|||
{ |
|||
_content = value; |
|||
if (_root is not null) |
|||
{ |
|||
_root.Content = value; |
|||
} |
|||
if (value != null) |
|||
{ |
|||
value.DataContext = DataContext; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override HandleRef BuildWindowCore(HandleRef hwndParent) |
|||
{ |
|||
_root = new EmbeddableControlRoot(); |
|||
_root.Content = _content; |
|||
_root.Prepare(); |
|||
_root.Renderer.Start(); |
|||
|
|||
var handle = _root.TryGetPlatformHandle()?.Handle |
|||
?? throw new InvalidOperationException("WpfAvaloniaHost is unable to create EmbeddableControlRoot."); |
|||
|
|||
if (PresentationSource.FromVisual(this) is HwndSource source) |
|||
{ |
|||
_ = UnmanagedMethods.SetParent(handle, source.Handle); |
|||
} |
|||
|
|||
return new HandleRef(_root, handle); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override void DestroyWindowCore(HandleRef hwnd) |
|||
{ |
|||
_root?.Dispose(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue