首先,我有一个应用程序使用Microsoft AddIn Framework(MAF)从插件获取WPF UI(您可以按this Microsoft example创建一个)。这个工作正常,直到插件内容足够大,主表单需要滚动。当发生这种情况时,它会滚动到它应该的边界之外。
在图片中,当您向下滚动时,Plugin Label Top
会超过Main Label Top
,而在底部,您只会看到Plugin Label Bottom
。我的主要表单代码如下:
<Window x:Class="WpfAddinTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:local="clr-namespace:WpfAddinTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Background="DarkGray">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Main Label Top"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ContentControl Name="PluginHolder"/>
</ScrollViewer>
<Label Grid.Row="2" Content="Main Label Bottom"/>
</Grid>
</Window>
ContentControl
是插件用户界面的内容,我不明白为什么插件用户界面会覆盖它的父控件。我尝试将其置于不同类型的控件中,例如DockPanel
和Grid
,一切都以相同的方式运行。
是否有一种特殊的方法可以让它正常运作?
如果需要更多代码,我很乐意发布,https://github.com/middas/WpfAddInTest是我完整的示例项目,可以证明这一点。
编辑:在WPF检查器中加载表单,我只能看到AddInHost
控件,它不会显示ContentControl
中的任何单个控件。这与它有关吗?
编辑2:在尝试任何我能想到的事情时,我在想,当它放入控件时可能没有达到正确的高度,所以我让插件返回所需的高度并根据返回的内容手动设置ContentPlaceholder
的高度;没运气。这是我试过的:
我已将GetInt()
的AddIn合约更新为GetHeight()
,并且在插件上我现在有了这个方法:
public double GetHeight()
{
_Control.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
return _Control.DesiredSize.Height;
}
然后在托管表单上,我现在有了这个:
public MainWindow()
{
_PluginPath = System.IO.Path.Combine(Environment.CurrentDirectory, "Pipeline");
_AddInPath = System.IO.Path.Combine(_PluginPath, "AddIns");
InitializeComponent();
var warnings = new List<string>(AddInStore.Update(_PluginPath));
_PluginToken = AddInStore.FindAddIns(typeof(IPlugin), _PluginPath, _AddInPath).FirstOrDefault();
_Plugin = _PluginToken.Activate<IPlugin>(AddInSecurityLevel.FullTrust);
var control = _Plugin.GetControl();
PluginHolder.Height = _Plugin.GetHeight();
PluginHolder.Content = control;
}
编辑3:尝试强制ZIndex似乎也不会影响它。
Panel.SetZIndex(control, -1);
答案 0 :(得分:0)
我相信我终于找到了问题所在。我认为问题是因为插件用户界面在AppDomain之外,ScrollViewer
并不知道如何正确剪辑内容。我最终做的工作是创建一个回调主UI,插件可以使用它给它需要适应的高度。如果插件需要滚动,插件可以用它自己处理它ScrollViewer
。
以下是更新后的合同:
[AddInContract]
public interface IPluginContract : IContract
{
INativeHandleContract GetControl();
double GetHeight();
void SetHostCallback(IHostCallbackContract callback);
}
IHostCallbackContract:
public interface IHostCallbackContract : IContract
{
double GetHeight();
}
现在,在插件返回Control
之前,它可以设置主窗体给出的高度:
public FrameworkElement GetControl()
{
if (_Callback != null)
{
_Control.SetHeight(_Callback.GetHeight());
}
return _Control;
}
我已使用整个工作解决方案更新了我的Git仓库(https://github.com/middas/WpfAddInTest)。现在唯一的问题是滚动不是双重缓冲,所以它会闪烁。我不得不忍受这一点,因为它没有出现,但由于通过DirectX进行WPF渲染,有一种方法可以修复。