Search code examples
wpfcanvaswpfdatagrid

WPF canvas with relative position


I have this DataGrid and this Canvas:

<DataGrid Canvas.ZIndex="1" x:Name="dgTimeline"/>

<Canvas Height="30" Width="999" Canvas.ZIndex="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="71,387,0,0">
    <Line Name="time" X1="0" Y1="0" X2="0" Y2="24" Stroke="Black" StrokeThickness="2"/>
</Canvas>

Which results in: enter image description here

However, when I move the horizontal scroll bar of the DataGrid the Canvas obviously stays on its position because its parent is the Window and not the DataGrid:enter image description here

Is it possible to keep Canvas' position relative to the DataGrid instead of its parent in such a way that when scrolling the DataGrid the Canvas would stay stationary as it was a DataGrid's element? I tried to put the Canvas inside of the DataGrid but that didn't work.


Solution

  • You can add horizontal scrollbar to canvas and then try to synchronize the horizontal scrolls of canvas and datagrid. something like ...

    private void dataGrid_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        canvasScrollViewer.ScrollToHorizontalOffset(e.HorizontalOffset);
    }
    
    private void canvasScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ScrollViewer dgScrollViewer = GetScrollViewerInstance();
        dgScrollViewer.ScrollToHorizontalOffset(e.HorizontalOffset);
    }
    
    private ScrollViewer GetScrollViewerInstance()
    {
        var ctrl = VisualTreeHelper.GetChild(dataGrid, 0);
        if (ctrl is Border)
        {
            var ctrl1 = VisualTreeHelper.GetChild(ctrl, 0);
            if (ctrl1 is ScrollViewer)
            {
                dgScrollViewer = ctrl1 as ScrollViewer;
            }
        }
    }
    

    This code is just to give you an idea of how to do it and not a actual working code. You set the HorizontalScrollBarVisibility for Canvas to Hidden if you don't want to show it. You will not need the second event handler in that case.