Browse Source

WPF embedding improvements

pull/1016/head
Nikita Tsukanov 9 years ago
parent
commit
3126901721
  1. 11
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml
  2. 5
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs
  3. 2
      src/Avalonia.Layout/Layoutable.cs
  4. 12
      src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj
  5. 35
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs
  6. 11
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

11
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml

@ -1,6 +1,7 @@
<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:local="clr-namespace:WindowsInteropTest"
@ -15,6 +16,16 @@
<Calendar/>
</StackPanel>
</GroupBox>
<GroupBox Header="Avalonia button" DockPanel.Dock="Bottom">
<wpf:WpfAvaloniaHost >
<av:Button Content="Avalonia button"/>
</wpf:WpfAvaloniaHost>
</GroupBox>
<GroupBox Header="AvBtn" DockPanel.Dock="Right">
<wpf:WpfAvaloniaHost x:Name="RightBtn">
<av:Button Content="Avalonia button 2"/>
</wpf:WpfAvaloniaHost>
</GroupBox>
<GroupBox Header="Avalonia">
<wpf:WpfAvaloniaHost x:Name="Host"/>
</GroupBox>

5
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs

@ -32,6 +32,11 @@ namespace WindowsInteropTest
{
view.AttachDevTools();
};
var btn = (Avalonia.Controls.Button) RightBtn.Content;
btn.Click += delegate
{
btn.Content += "!";
};
}
}

2
src/Avalonia.Layout/Layoutable.cs

@ -370,7 +370,7 @@ namespace Avalonia.Layout
/// <summary>
/// Invalidates the measurement of the control and queues a new layout pass.
/// </summary>
public void InvalidateMeasure()
public virtual void InvalidateMeasure()
{
if (IsMeasureValid)
{

12
src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj

@ -68,6 +68,10 @@
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
<Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project>
<Name>Avalonia.DotNetFrameworkRuntime</Name>
</ProjectReference>
<ProjectReference Include="..\..\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
@ -92,6 +96,14 @@
<Project>{fb05ac90-89ba-4f2f-a924-f37875fb547c}</Project>
<Name>Avalonia.Cairo</Name>
</ProjectReference>
<ProjectReference Include="..\..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\Avalonia.Win32\Avalonia.Win32.csproj">
<Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
<Name>Avalonia.Win32</Name>

35
src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs

@ -1,29 +1,35 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Platform;
using Avalonia.Styling;
namespace Avalonia.Win32.Interop.Wpf
{
public class WpfAvaloniaHost : FrameworkElement, IDisposable
[ContentProperty("Content")]
public class WpfAvaloniaHost : FrameworkElement, IDisposable, IAddChild
{
private WpfTopLevelImpl _impl = new WpfTopLevelImpl();
private WpfTopLevelImpl _impl;
private readonly SynchronizationContext _sync;
public WpfAvaloniaHost()
{
_sync = SynchronizationContext.Current;
_impl = new WpfTopLevelImpl();
_impl.ControlRoot.Prepare();
_impl.Visibility = Visibility.Visible;
AddLogicalChild(_impl);
AddVisualChild(_impl);
}
public object Content
{
@ -47,9 +53,13 @@ namespace Avalonia.Win32.Interop.Wpf
}
}
protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
=> _impl.ControlRoot.MeasureBase(constraint.ToAvaloniaSize()).ToWpfSize();
protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
{
_impl.InvalidateMeasure();
_impl.Measure(constraint);
return _impl.DesiredSize;
}
protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
{
_impl.Arrange(new System.Windows.Rect(arrangeSize));
@ -76,5 +86,18 @@ namespace Avalonia.Win32.Interop.Wpf
GC.SuppressFinalize(this);
}
}
void IAddChild.AddChild(object value)
{
if (Content == null)
Content = value;
else
throw new InvalidOperationException();
}
void IAddChild.AddText(string text)
{
//
}
}
}

11
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@ -33,6 +33,15 @@ namespace Avalonia.Win32.Interop.Wpf
public EmbeddableControlRoot ControlRoot { get; }
internal ImageSource ImageSource { get; set; }
public class CustomControlRoot : EmbeddableControlRoot
{
public override void InvalidateMeasure()
{
base.InvalidateMeasure();
((FrameworkElement)PlatformImpl)?.InvalidateMeasure();
}
}
public WpfTopLevelImpl()
{
PresentationSource.AddSourceChangedHandler(this, OnSourceChanged);
@ -158,6 +167,8 @@ namespace Avalonia.Win32.Interop.Wpf
_ttl.Input?.Invoke(new RawMouseWheelEventArgs(_mouse, (uint) e.Timestamp, _inputRoot,
e.GetPosition(this).ToAvaloniaPoint(), new Vector(0, e.Delta), GetModifiers()));
protected override void OnMouseLeave(MouseEventArgs e) => MouseEvent(RawMouseEventType.LeaveWindow, e);
protected override void OnKeyDown(KeyEventArgs e)
=> _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint) e.Timestamp, RawKeyEventType.KeyDown,
(Key) e.Key,

Loading…
Cancel
Save