MDX / SlimDX弄乱了WPF滚动条?

时间:2009-06-29 19:52:47

标签: c# wpf winforms interop directx

我有一个非常简单的WPF用户控件,它与Windows窗体应用程序混合在一起。它有一个列表框,可以在没有拇指的情况下呈现其滚动条(下图)。我将其缩小为我的应用程序中使用Managed DirectX(MDX)的插件。如果我删除插件,滚动条就好了。我知道MDX已被弃用,但我认为今天不是考虑升级的日子。有没有人见过他们的滚动条搞砸了,或者知道我该怎么办?

我应该补充一点,这个控件也存在于一个插件中。 2个插件无法相互引用。

alt text

<UserControl x:Class="MAAD.Plugins.Experiment.Visual.TestEditor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="403" Width="377">
<ListBox Margin="12" Name="listBox1" />
</UserControl>

更新:您可以阅读以下解决方案。

8 个答案:

答案 0 :(得分:2)

我也见过这个错误。它本身不是SlimDX问题,而是由于DirectX在x87 FP堆栈上使用32位数学运算。

初始化设备时使用FpuPreserve标志,问题应该消失。

答案 1 :(得分:2)

事实证明,我在与客户合作时偶然发现了解决方案。如果将CreateFlags.FpuPreserve标志添加到设备创建中,滚动条应该恢复正常。

答案 2 :(得分:1)

我的建议是摆脱你的MDX插件。

我使用过WPF和MDX,但不是在同一个项目中。两个库都与DirectX通信,最终将状态存储在本机级别,这可能会导致问题。使用WPF我有与我的视频驱动程序相关的渲染问题,修复方法是将视频驱动程序升级到更新版本。

初始化DirectX会影响DirectX(和您的CPU!)为整个应用程序执行的方式。例如,默认情况下初始化MDX时,无论您如何声明原始值,它都会将CPU设置为以单精度进行所有浮点计算。正如您可能想象的那样,这导致了很长时间以来为什么我们在应用程序和单元测试中得到不同的结果。

我怀疑当MDX正在初始化时,它正在以某种方式启用或禁用影响WPF管道的图形卡中的某些功能或设置(或可能是某些软件设置)。

我希望我能提供更多帮助。祝你好运。

答案 3 :(得分:1)

我也有这个问题。正如mpg发现的那样,将D3DCREATE_FPU_PRESERVE标志添加到设备创建中将修复它。如果有人想知道代码是什么样的:

d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
(HWND)this->Handle.ToPointer(),
D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
&d3dpp,
p);

答案 4 :(得分:0)

您是否尝试过SlimDX而不是MDX? SlimDX是DX的新包装器,正在积极开发中。也许你可以在SlimDX中使用你的MDX-Plugin,并且滚动条功能正常。

彼得对WPF和MDX的互动是正确的。 WPF在内部使用DirectX。因此,更改MDX(或SlimDX)中的设置可以更改WPF的行为方式。您还可以尝试查看WPF滚动条的代码(例如使用.NET Reflector,IDA,无论您需要什么)并检查Scrollbar依赖的设置。

答案 5 :(得分:0)

我在WPF的背景下提到了之前关于MDX的海报的保留。尽管如此,还有一次进入黑暗:

您是否尝试过针对.NET Framework 3.5 SP1的控件?有关DirectX / Direct3D互操作性和性能的重要工作,例如:

其中一些增强功能可能最终会对您的问题产生积极的副作用。

答案 6 :(得分:0)

我接受了大家的建议并将我的应用程序移植到SlimDX。这不是太糟糕(几乎每个类/方法/字段在SlimDX中都与MDX完全相同)。不幸的是,我仍然有同样的问题。我能够将SlimDX和MDX简化为以下应用程序:

public partial class MainForm : Form
{
    Direct3D Direct3D = new Direct3D();
    Panel slimPanel = new Panel();

    public MainForm()
    {
        InitializeComponent();

        CreateDevice();
        BuildWindows();
    }

    void BuildWindows()
    {
        var listBox = new System.Windows.Controls.ListBox();
        listBox.ItemsSource = Enumerable.Range(0, 100);
        var elementHost = new ElementHost();
        elementHost.Child = listBox;

        elementHost.Dock = DockStyle.Fill;
        Controls.Add(elementHost);
        slimPanel.Dock = DockStyle.Left;
        Controls.Add(slimPanel);
    }

    void CreateDevice()
    {
        PresentParameters presentParams = new PresentParameters();
        presentParams.BackBufferHeight = slimPanel.ClientRectangle.Height;
        presentParams.BackBufferWidth = slimPanel.ClientRectangle.Width;
        presentParams.DeviceWindowHandle = slimPanel.Handle;

        var device = new Device(Direct3D, 0, DeviceType.Hardware, slimPanel.Handle, CreateFlags.HardwareVertexProcessing, presentParams);
    }
}

滚动条不会显示。我能够让滚动条显示我是否确保列表框在创建设备之前进行绘制。

最后的解决方案是在构造函数中将WPF ListBox添加到我的表单中,然后在表单完成加载后将其删除。我不确定这是否是WPF或DirectX中的错误,我可能会尝试向Microsoft提交错误。

顺便说一下,我不能让XNA引起这个问题。

答案 7 :(得分:0)

你在Vista吗?我们已经看到很多SlimDX / WPF在Vista目标下运行时通过创建Direct3D9Ex设备而不是正常设备而消失。