使用一个滚动条同时水平滚动列中的所有行

时间:2014-07-16 06:48:18

标签: wpf datagrid scrollviewer

如何使用DataGrid外部的滚动条水平滚动DataGrid中单列内的列表视图,确保每行同时滚动?

(我还希望滚动条的起始位置一直向右,这样在加载数据时列表视图中的最后一项是可见的)

我无法使用第三方库或dll。

非常感谢任何帮助。

非常感谢

修改

第一栏示例代码

<DataGridTemplateColumn Width="325" Header="Header Text" >  
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <ListBox ItemsSource="{Binding TrendList}" 
            BorderThickness="0" 
            Background="Transparent" 
            ScrollViewer.HorizontalScrollBarVisibility="Auto" 
            HorizontalAlignment="Center" 
            HorizontalContentAlignment="Center"
            >
            <ListBox.Resources>
                <Style TargetType="ScrollViewer">
                    <Setter Property="resex:ScrollSynchronizer.ScrollGroup" Value="Group1" />
                    <Setter Property="resex:ScrollSynchronizer.AlwaysScrollToEnd" Value="True" />
                </Style>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Label Margin="2,2,2,2" Width="25" Height="25"  
                        HorizontalAlignment="Center" VerticalAlignment="Center"
                        HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
                        Content="{Binding ArisingList.Count}"
                        FontWeight="Bold
                        >
                        <interact:Interaction.Triggers>
                            <interact:EventTrigger EventName="MouseDoubleClick">
                                <interact:InvokeCommandAction Command="{Binding OpenPCICommand}"
                                    CommandParameter="{Binding ArisingList}" />
                            </interact:EventTrigger>
                        </interact:Interaction.Triggers>
                        <Label.Style>
                            <Style TargetType="Label">
                                <Setter Property="Background" Value="Green"></Setter>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ArisingList.Count}" Value="0">
                                        <Setter Property="Background" Value="Red" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Label.Style>
                        <Label.ToolTip>
                            <TextBlock x:Name="pciID" Text="{Binding PciID, StringFormat='PCI Number : {0}'}" />
                        </Label.ToolTip>
                    </Label>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </DataTemplate>

这是我到目前为止所拥有的。滚动条全部在内部链接,但它们没有链接到任何外部滚动条

2 个答案:

答案 0 :(得分:1)

我设法使用附加属性

创建同步滚动行为

这可能会帮助您以某种方式实现目标

为此我还对您的模板进行了一些更改

  • ListBoxItemsControl
  • Wrapped ItemsControl in a ScrollViewer
  • 已添加ScrollHelper.IsSyncScrollEnabled&amp; ScrollHelper.ScrollValueScrollViewer
  • 向主Name
  • 添加了DataGrid

示例xaml

<Grid xmlns:l="clr-namespace:CSharpWPF">
    <DataGrid x:Name="dGrid" ItemsSource="{Binding MyDataSource}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="325"
                                    Header="Header Text">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ScrollViewer HorizontalScrollBarVisibility="Auto"
                                      VerticalScrollBarVisibility="Hidden"
                                      l:ScrollHelper.IsSyncScrollEnabled="true"
                                      l:ScrollHelper.ScrollValue="{Binding (l:ScrollHelper.ScrollValue),ElementName=dGrid,Mode=TwoWay}">
                            <ItemsControl ItemsSource="{Binding TrendList}">
                                <ItemsControl.ItemTemplate>
                                   ... your item template here
                                </ItemsControl.ItemTemplate>
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                            </ItemsControl>
                        </ScrollViewer>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
             ... other columns etc
        </DataGrid.Columns>
    </DataGrid>
</Grid>

ScrollHelper类

namespace CSharpWPF
{
    class ScrollHelper : DependencyObject
    {
        public static bool GetIsSyncScrollEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsSyncScrollEnabledProperty);
        }

        public static void SetIsSyncScrollEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsSyncScrollEnabledProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsSyncScrollEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsSyncScrollEnabledProperty =
            DependencyProperty.RegisterAttached("IsSyncScrollEnabled", typeof(bool), typeof(ScrollHelper), new PropertyMetadata(false, OnIsSyncScrollEnabledChanged));

        private static void OnIsSyncScrollEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ScrollViewer sv = d as ScrollViewer;
            if ((bool)e.NewValue)
                sv.ScrollChanged += sv_ScrollChanged;
            else
                sv.ScrollChanged -= sv_ScrollChanged;
        }

        static void sv_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (e.HorizontalChange != 0)
            {
                ScrollViewer sv = sender as ScrollViewer;
                SetScrollValue(sv, sv.HorizontalOffset);
            }
        }

        public static double GetScrollValue(DependencyObject obj)
        {
            return (double)obj.GetValue(ScrollValueProperty);
        }

        public static void SetScrollValue(DependencyObject obj, double value)
        {
            obj.SetValue(ScrollValueProperty, value);
        }

        // Using a DependencyProperty as the backing store for ScrollValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ScrollValueProperty =
            DependencyProperty.RegisterAttached("ScrollValue", typeof(double), typeof(ScrollHelper), new PropertyMetadata(0.0, OnScrollValueChange));

        private static void OnScrollValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ScrollViewer sv = d as ScrollViewer;
            if (sv != null)
            {
                double offset = (double)e.NewValue;
                if (sv.HorizontalOffset != offset)
                    sv.ScrollToHorizontalOffset(offset);
            }
        }
    }
}

结果是在所有滚动查看器之间同步滚动

result

<强>附加

如果您不想在所有行上显示滚动条,则可以使用触发器

例如

<Grid xmlns:l="clr-namespace:CSharpWPF">
    <DataGrid x:Name="dGrid">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="325"
                                    Header="Header Text">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ScrollViewer HorizontalScrollBarVisibility="Hidden"
                                      VerticalScrollBarVisibility="Hidden"
                                      x:Name="scroll"
                                      l:ScrollHelper.IsSyncScrollEnabled="true"
                                      l:ScrollHelper.ScrollValue="{Binding (l:ScrollHelper.ScrollValue),ElementName=dGrid,Mode=TwoWay}">
                            <ItemsControl ItemsSource="{Binding TrendList}">
                                <ItemsControl.ItemTemplate>
                                  ... your template here
                                </ItemsControl.ItemTemplate>
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                            </ItemsControl>
                        </ScrollViewer>
                        <DataTemplate.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="True">
                                <Setter TargetName="scroll"
                                        Property="HorizontalScrollBarVisibility"
                                        Value="auto" />
                            </Trigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

结果是单个滚动条滚动所有行数据

result

修改

获取默认滚动位置以显示itemscontrol中的最后一项,更改方法sv_ScrollChanged,如下所示

    static void sv_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ScrollViewer sv = sender as ScrollViewer;
        if (e.HorizontalChange != 0)
        {
            SetScrollValue(sv, sv.HorizontalOffset);
        }
        if (e.ExtentWidthChange != 0)
        {
            SetScrollValue(sv, e.ExtentWidth);
        }
    }

答案 1 :(得分:0)

如果我理解正确,您希望能够使用Width滚动DataGrid的{​​{1}},而。只要没有限制DataGrid ScrollBar的{​​{1}},就可以使用Width轻松完成此操作。试试这个:

DataGrid