0
votes

I am trying to create a settings grid where the user can apply a selected setting to the corresponding row and column header listboxes by clicking on the corresponding buttons in the grid.I want my control to behave like how a ms excel spreadsheet window behaves when you scroll. Below is the anatomy of the window I was able to come up with :

enter image description here

The image shows how I have designed the window. The List boxes A and B represent item and users respectively and the ItemsControl which is a grid of buttons act as cells which the users click on to apply the settings they want to the corresponding A and B.

The problem I have is, I have to be able to do two things

a) When the user scrolls left to right or vice verse - Listbox A is stationary the button grid and Listbox B scroll in synchronous

b) When the user scrolls Top to Bottom or vice verse - Listbox B is stationary the button grid and Listbox A scroll in synchronous

As of now I have put Listbox A and the button grid in a common scroll viewer and I am able to achieve condition b). But not condition a). In order to achieve both conditions a) and b) I will have to decouple Listbox A and the button grid and link their Scroll properties. So I tried something like this

ScrollViewer scrollView = null;
    ScrollViewer scrollView2 = null;


    void scrollView_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        var newOffset = e.VerticalOffset;

        if ((null != scrollView) && (null != scrollView2))
        {
            scrollView.ScrollToVerticalOffset(newOffset);
            scrollView2.ScrollToVerticalOffset(newOffset);
        }
    }


    private ScrollViewer getScrollbar(DependencyObject dep)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
        {
            var child = VisualTreeHelper.GetChild(dep, i);
            if ((null != child) && child is ScrollViewer)
            {
                return (ScrollViewer)child;
            }
            else
            {
                ScrollViewer sub = getScrollbar(child);
                if (sub != null)
                {
                    return sub;
                }
            }
        }
        return null;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        scrollView = getScrollbar(dataGrid1);
        scrollView2 = getScrollbar(dataGrid2);

        if (null != scrollView)
        {
            scrollView.ScrollChanged += new ScrollChangedEventHandler(scrollView_ScrollChanged);
        }
        if (null != scrollView2)
        {
            scrollView2.ScrollChanged += new ScrollChangedEventHandler(scrollView_ScrollChanged);
        }
    }

I modified the code to suit my needs of course but when i decoupled Listbox A and the button grid they were not aligned with each other anymore and when ever i scrolled the button grid (or scroll viewer) the list boxes A and B would not scroll in sync, they scrolled magnitudes faster than the scroll viewer.

In conclusion I need to create a control where the users can assign selected settings to items in List boxes A and B by selecting the corresponding button in the button grid. the List Boxes A and B must be perfectly aligned with their corresponding settings button in the buttons grid. And I would like to let the users perform scrolling actions a) and b) as explained above. I need help/ tips regarding this issue.

P.S : the scroll sync code is from this stackoverflow question and the button grid idea is from here

1

1 Answers

0
votes

I'm not sure I fully understand the question but you can revise your code using this approach:

    <StackPanel Grid.IsSharedSizeScope="True">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="col1"/>
                <ColumnDefinition SharedSizeGroup="col2"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="some text"/>
            <TextBlock Text="some other text" Grid.Column="1"/>
        </Grid>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="col1"/>
                <ColumnDefinition SharedSizeGroup="col2"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="text"/>
            <TextBlock Text="a very very long text" Grid.Column="1"/>
        </Grid>
    </StackPanel>