简体   繁体   English

WindowsFormsHost中的WPF,GridSplitter和DirectX

[英]WPF, GridSplitter, and DirectX in a WindowsFormsHost

I'm trying to make a modern editor for my game using WPF, a GridSplitter and a DirectX rendered WindowsFormsHostControl. 我正在尝试使用WPF,GridSplitter和DirectX呈现的WindowsFormsHostControl为我的游戏制作现代编辑器。 I can draw fine with C++ DirectX routines called from the main C# program, but I'm facing a strange problem. 我可以使用从C#主程序调用的C ++ DirectX例程进行绘图,但是我面临一个奇怪的问题。 Next is an image of my editor window: 接下来是我的编辑器窗口的图像:

在此处输入图片说明

The center area is C++ DirectX rendered one, on the left and right areas I have WPF controls. 中心区域是C ++ DirectX渲染的一个区域,在左右区域我具有WPF控件。 The left area as you can see is splitted with a WPF GridSplitter. 如您所见,左侧区域被WPF GridSplitter分割。

I can drag without any problems the GridSplitter up and down just before I call the DirectX CreateDevice() function, but when that function is called and DirectX rendering is started I can also drag the GridSplitter but it returns in the original center position after some milliseconds if I make tiny mouse movements, while if I make "big" movements with mouse the GridSplitter moves accordingly (more or less.. but I lost precision and an user would think its really crap). 我可以在调用DirectX CreateDevice()函数之前向上和向下拖动GridSplitter,而不会出现任何问题,但是当调用该函数并启动DirectX渲染时,我也可以拖动GridSplitter,但它会在几毫秒后返回原始中心位置如果我进行微小的鼠标移动,而如果我使用鼠标进行“大”移动,则GridSplitter会相应移动(或多或少..但是我失去了精确度,用户会认为它确实很糟糕)。

Its not a machine speed problem, even if I disable rendering (but I continue to have the DirectX device attached to the WindowsFormsHost hwnd) the anomaly persists. 即使我禁用了渲染(但我仍然将DirectX设备连接到WindowsFormsHost hwnd),也不是机器速度问题,异常仍然存在。 It seems that once the DirectX device is created it "eats" events to WPF. 似乎一旦创建DirectX设备,它就会将事件“吃”到WPF。 Have I forgot something during DirectX or some WPF initialization? 我在DirectX或某些WPF初始化过程中忘记了什么吗? There are ways to eliminate this problem? 有消除这个问题的方法吗?

The only solution I'm thinking now is to close the DirectX device while the user is dragging the GridSplitter and recreate it as the user finishes dragging, but I'm hoping to resolve the problem, not avoiding it! 我现在想的唯一解决方案是在用户拖动GridSplitter时关闭DirectX设备,并在用户完成拖动后重新创建它,但是我希望解决该问题,而不是避免它! Thank you really a lot for your replies. 非常感谢您的答复。

Following is the current skeleton of my xaml code, I just removed some (here unuseful) parts, note that in the panel contained in the WindowsFormsHost I add at runtime a WinForms Control (a class I derived from Winforms Control class) from where I take the Window handle and pass it to a C++ routine that calls DirectX CreateDevice() function. 以下是我的xaml代码的当前框架,我刚刚删除了一些(在这里无用)部分,请注意,在WindowsFormsHost包含的面板中,我在运行时添加了WinForms控件(我从Winforms控件类派生的类)窗口句柄,并将其传递给调用DirectX CreateDevice()函数的C ++例程。

    <Grid Name="ccgrid1" ClipToBounds="False" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto">

        </RowDefinition>
        <RowDefinition Height="*">

        </RowDefinition>

        <RowDefinition Height="Auto">

        </RowDefinition>

    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition />

       <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Row="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ListBox Grid.Row="0" IsEnabled="True" HorizontalAlignment="Stretch" Name="ccCaratteri" VerticalAlignment="Stretch"
                 HorizontalContentAlignment="Center" VerticalContentAlignment="Stretch" ClipToBounds="False"
                 Background="#FFAD4545" Width="Auto" SelectionChanged="ccCaratteri_SelectionChanged">
            <ListBox.BindingGroup>
                <BindingGroup />
            </ListBox.BindingGroup>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True"
                           Width="{Binding RelativeSource={RelativeSource FindAncestor,
                                AncestorType={x:Type ListBox}},
                                Path=ActualWidth}"/>
                </ItemsPanelTemplate>

            </ListBox.ItemsPanel>
        </ListBox>
        <GridSplitter Grid.Row="1"  Height="10" ResizeDirection="Rows" HorizontalAlignment="Stretch">
            <GridSplitter.Template>
                <ControlTemplate TargetType="{x:Type GridSplitter}">
                    <Grid>
                        <Button Content="⁞" />
                        <Rectangle Fill="#00FFFFFF" />
                    </Grid>
                </ControlTemplate>
            </GridSplitter.Template>
        </GridSplitter>



        <TreeView x:Name="t1" Grid.Row="2" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
                  KeyboardNavigation.TabNavigation="Cycle">

            <TreeViewItem Name="RTBContainer" Header="Global" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Focusable="False" IsExpanded="True" >
                <Border BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1,1,1,0" >
                    <Grid  HorizontalAlignment="Stretch">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Row="0" Grid.Column="0" Content="Kerning" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Padding="0,0,0,0"/>
                        <local:CustomNumericTextbox  Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch"
                        HorizontalContentAlignment="Stretch" BorderThickness="0" CJNumOfVisibleChars="-1" CJRangeValidation="-100,100"
                        CJSigned="True" CJMaxLength="3"></local:CustomNumericTextbox>
                    </Grid>
                </Border>
                <Border BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1">
                    <Grid  HorizontalAlignment="Stretch">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Row="0" Grid.Column="0" Content="Leading" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Padding="0,0,0,0" />
                        <local:CustomNumericTextbox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" BorderThickness="0"
                                                    CJNumOfVisibleChars="-1" CJRangeValidation="-100,100" CJSigned="True" CJMaxLength="3"></local:CustomNumericTextbox>
                    </Grid>
                </Border>
            </TreeViewItem>

        </TreeView>
    </Grid>
    <WindowsFormsHost Grid.Row="1" Grid.Column="1" Background="Black" >
        <wf:Panel x:Name="ccWinFormsPanel"/>
            <!--<wf:Button x:Name="ccFormButton" Width="1200"/>-->
        <!--<wf:MaskedTextBox x:Name="ccFormControl" Mask="00/00/0000"/>-->
    </WindowsFormsHost>
    <ScrollViewer Grid.Row="1" Grid.Column="2" VerticalScrollBarVisibility="Visible"  HorizontalScrollBarVisibility="Visible">
        <Canvas Name="ccCanvasBitmap" Height="Auto"  Background="Aquamarine" ClipToBounds="True"   />
    </ScrollViewer>
    <Menu Grid.Row="0" Grid.Column="0" DockPanel.Dock="Top" Grid.ColumnSpan="3" VerticalAlignment="Bottom" Height="21">
        <MenuItem Header="F_ile">
            <MenuItem Header="_New Font..." Name="menuNewFont" Click="menuNewFont_Click"/>
            <MenuItem Header="_Open Font..." Name="menuOpenFont" Click="menuOpenFont_Click"/>
            <MenuItem Header="_Import Image..." Name="menuImportImage" Click="menuImportImage_Click"/>

        </MenuItem>
    </Menu>

    <StatusBar Grid.Row="2" Grid.ColumnSpan="3" Height="auto">
        <Label>Zoom</Label>
        <ComboBox Name="ccZoom" SelectionChanged="ccZoom_SelectionChanged" x:FieldModifier="public">

        </ComboBox>
    </StatusBar>
</Grid>

It seems a well known WPF GridSplitter problem, and for some unknown motivations in my case it arises after I call DirectX CreateDevice() function, this is the discussion that helped me: 这似乎是一个众所周知的WPF GridSplitter问题,由于某些未知的动机,在我调用DirectX CreateDevice()函数后出现了这个问题,这对我有帮助:

WPF GridSplitter WPF GridSplitter

My current workaround is to set the GridSplitter DragIncrement value to a larger value, 20. While I'm very angry for all the time I losted on this (thanks Microsoft..), that workaround seems a good compromise. 我当前的解决方法是将GridSplitter DragIncrement值设置为更大的值20。尽管我为此一直感到很生气(感谢Microsoft ..),但该解决方法似乎是一个不错的折衷方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM