WPF GridSplitter видимость - PullRequest
0 голосов
/ 06 апреля 2009

У меня проблема с видимостью GridSplitter.

В этом, что бы я ни размещал, Winform DataGridView. При перетаскивании GridSplitter правильно отображается на других элементах управления. Но не в этой сетке. Фактически, все, что я размещаю вместо Datagridview, становится верхним элементом управления, что заставляет GridSplitter скрываться за ним.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Name="rowForButton"/>
        <RowDefinition Name="rowForGridSplitter" Height="Auto" MinHeight="81" />
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Height="50" Width="110" Content="Button in First Row"/>
    <my:WindowsFormsHost Panel.ZIndex="0" Grid.Row="1"  Margin="30,11,138,0" x:Name="winHost" Height="58" VerticalAlignment="Top" OpacityMask="Transparent">            
        <win:DataGridView x:Name="dataGridView"></win:DataGridView>
    </my:WindowsFormsHost>        
    <GridSplitter  BorderThickness="1" Panel.ZIndex="1" Grid.Row="1" HorizontalAlignment="Stretch" Height="5" ShowsPreview="True" VerticalAlignment="Top">
    </GridSplitter>
</Grid>

Ответы [ 6 ]

1 голос
/ 18 мая 2012

Я также столкнулся с этой проблемой, есть мое решение:

var splitter = new GridSplitter()
        {
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch,
            FocusVisualStyle = null,
            ShowsPreview = true,
            Background = new SolidColorBrush(new Color() { R = 1, G = 1, B = 1, A = 1 }),
        };

// non-style / essential window which will display over your WinForm control
var PopupWindowForSplitter = new PopupWindow()
        {
            Background = new SolidColorBrush(new Color() { R = 1, G = 1, B = 1, A = 1 }),
            Visibility = Visibility.Collapsed
        };
PopupWindowForSplitter.Show();
...

Point _ptForSplitterDrag = new Point(0,0);

splitter.DragStarted += (o, e) =>
        {
            var pt = splitter.PointToScreen(new Point());
            _ptForSplitterDrag = splitter.PointToScreen(Mouse.GetPosition(splitter));
            PopupWindowForSplitter.Left = pt.X;
            PopupWindowForSplitter.Top = pt.Y;
            PopupWindowForSplitter.Height = splitter.ActualHeight;
            PopupWindowForSplitter.Width = splitter.ActualWidth;
            PopupWindowForSplitter.Activate();
            PopupWindowForSplitter.Visibility = Visibility.Visible;
        };
        splitter.DragDelta += (o, e) =>
        {
            var pt = splitter.PointToScreen(Mouse.GetPosition(splitter)) - _ptForSplitterDrag
                + splitter.PointToScreen(new Point());
            if (splitter.ResizeDirection == GridResizeDirection.Rows)
            {
                PopupWindowForSplitter.Top = pt.Y;
            }
            else
            {
                PopupWindowForSplitter.Left = pt.X;
            }
        };
        splitter.DragCompleted += (o, e) =>
        {
            var initializeData = typeof(GridSplitter).GetMethod("InitializeData", BindingFlags.NonPublic | BindingFlags.Instance);
            var moveSplitter = typeof(GridSplitter).GetMethod("MoveSplitter", BindingFlags.NonPublic | BindingFlags.Instance);
            if (moveSplitter != null && initializeData != null)
            {
                initializeData.Invoke(splitter, new object[] { true });

                var pt = splitter.PointToScreen(Mouse.GetPosition(splitter)) - _ptForSplitterDrag;
                if (splitter.ResizeDirection == GridResizeDirection.Rows)
                {
                    moveSplitter.Invoke(splitter, new object[] { 0, pt.Y });
                }
                else
                {
                    moveSplitter.Invoke(splitter, new object[] { pt.X, 0 });
                }
            }
            PopupWindowForSplitter.Visibility = Visibility.Collapsed;
        };

Возможно, в моем описании есть некоторые проблемы из-за моего плохого английского, но я думаю, что кода достаточно, чтобы объяснить это.

1 голос
/ 06 апреля 2009

Обычно вы должны либо поместить GridSplitter в его собственную ячейку сетки, либо убедиться, что через поля никакие элементы управления не могут перекрывать его. Но я не знаю, относится ли это именно к вам здесь. Смотри также здесь .

0 голосов
/ 01 июня 2015

Решением было бы добавить метку «Windows Form» внутри разделителя сетки и сделать это программно после добавления DataGridView, чтобы он отображался поверх него, как показано ниже:

void AddLabelToSplitter()
{
string template =
    @" <ControlTemplate 
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:mn='clr-namespace:MyNameSpace;assembly=MyAssembly'  
xmlns:wf='clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms'   
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' TargetType='{x:Type GridSplitter}'>
            <mn:ExtendedWindowsFormsHost x:Name='Grid_Splitter_WindowsFormsHost' HorizontalAlignment='Stretch'  VerticalAlignment='Stretch'>
                <wf:Label Dock='Fill' BackColor='DarkGray'></wf:Label>
            </mn:ExtendedWindowsFormsHost>
        </ControlTemplate>";
Grid_Splitter.Template = (ControlTemplate)XamlReader.Parse(template);
}

Использование обычного хоста форм Windows не будет работать, так как он не будет передавать события мыши в сплиттер, поэтому используйте вместо него ссылку ExtendedWindowsFormsHost из приведенной ниже ссылки:

Сохранить всплывающие события мыши из WindowsFormsHost на

0 голосов
/ 06 апреля 2009

В вашей ситуации самым быстрым решением было бы переместить GirdSplitter в ряд с помощью кнопки:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Name="rowForButton"/>
        <RowDefinition Name="rowForGridSplitter" Height="Auto" MinHeight="81" />
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Height="50" Width="110" Content="Button in First Row"/>
    <my:WindowsFormsHost Panel.ZIndex="0" Grid.Row="1"  Margin="30,11,138,0" x:Name="winHost" Height="58" VerticalAlignment="Top" OpacityMask="Transparent">            
        <win:DataGridView x:Name="dataGridView"></win:DataGridView>
    </my:WindowsFormsHost>        
    <GridSplitter  BorderThickness="1" Panel.ZIndex="1" Grid.Row="0" HorizontalAlignment="Stretch" Height="5" ShowsPreview="True" VerticalAlignment="Bottom">
    </GridSplitter>
</Grid>

Теперь просто отрегулируйте поля, чтобы убедиться, что между кнопкой и разделителем сетки есть свободное пространство.

0 голосов
/ 06 апреля 2009

Элементы управления Windows Forms всегда отображаются отдельно от элементов управления WPF, и в результате они всегда отображаются над приложением WPF.

См. Размещение окна Microsoft Win32 в WPF (подзаголовок Заметные различия в поведении вывода ) для получения дополнительной информации.

0 голосов
/ 06 апреля 2009

Попробуйте использовать WPF-собственный элемент управления DataGrid. Есть несколько коммерческих сторонних элементов управления, которые вы можете купить, или вы можете взглянуть на один из предоставленных Microsoft (в настоящее время все еще в CTP):

...