DataGrid需要水平滚动条和调整大小的功能

时间:2019-01-17 15:30:39

标签: c# wpf xaml

我在DataGrid中有一个ScrollViewer。我有两个问题之一:

  1. 缩小宽度并且剪切掉项目文本(H2列不够宽)时,不会出现滚动条。但是,我拥有的两列的大小适当,无法在屏幕外调整大小。 XAML(基本上)是:

    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <DataGrid Width="{Binding ActualWidth, 
                      RelativeSource={RelativeSource AncestorType={x:Type ScrollViewer}}}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="H1" Width="40" MinWidth="35"/>
                <DataGridTextColumn Header="H2" Width="*" MinWidth="47"/>
            </DataGrid.Columns>
        </DataGrid>
    </ScrollViewer>
    
  2. 当我有一个可以使用的滚动条时,可以调整列的大小,以便右侧的视图不可见(中心分隔线可以向右移动足够远,以至于整个列都不可见)。 XAML:

    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Grid>
            <DataGrid Width="{Binding ActualWidth, 
                          RelativeSource={RelativeSource AncestorType={x:Type Grid}}}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="H1" Width="40" MinWidth="35"/>
                    <DataGridTextColumn Header="H2" Width="*" MinWidth="47"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </ScrollViewer>
    

(注意:在这两种情况下,我都排除了itemsource,因为我不认为这个问题是必要的,我可以添加它,并在需要时添加后端代码)。

>

我想象这与绑定DataGrid的元素有关(也许Grid元素的大小没有适当调整,我尝试绑定{{1} }到Grid,但问题与(1)相同。  我还注意到,当垂直内容被切掉并且垂直滚动条出现(同时出现)时,滚动条的确出现了(两个实例)。有没有建议使用滚动条并能够确保列不会离开屏幕?

2 个答案:

答案 0 :(得分:1)

问题是DataGrid的宽度绑定到ScrollViewer的宽度

<DataGrid Width={Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}">

DataGrid永远不会比ScrollViewer宽,因此不会启用滚动条。

将Horizo​​ntalAlignment设置为“ Stretch”将实现我认为您正在寻找的布局并允许滚动。因此,DataGrid元素应为:

 <DataGrid HorizontalAlignment="Stretch">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="H1" Width="40" MinWidth="35"/>
                    <DataGridTextColumn Header="H2" Width="*" MinWidth="47"/>
                </DataGrid.Columns>
            </DataGrid>

答案 1 :(得分:1)

这就是我通过使用VisualTreeHelper想到的。

创建一个方法,该方法可以在可视树中搜索特定类型的子级。我找到了一种可以修改的寻找父对象(反向)的方法。 https://stackoverflow.com/a/636456/1640271

public static T FindVisualChild<T>(DependencyObject parent)
    where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
        DependencyObject childObject = VisualTreeHelper.GetChild(parent, i);

        if (childObject == null) return null;

        if (childObject is T obj)
        {
            return obj;
        }
        else
        {
            return FindVisualChild<T>(childObject);
        }
    }

    return null;
}

我背后的代码包括创建一个常量,一个类变量以及使用两个Window事件触发器。

常数

(对Window的宽度施加限制,以确保始终可以看到第二列的至少一部分)。

private const double _item2MinViewableWidth = 100;

变量

(用于从Grid的{​​{1}}内部的可视树中捕获ScrollView)。

DataGrid

事件

private Grid _innerGrid;

以下是我的XAML:

private void Window_ContentRendered(object sender, EventArgs e)
{
    _innerGrid = UIHelper.FindVisualChild<Grid>(dataGrid);

    item2Column.MinWidth = _item2MinViewableWidth;

    item1Column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
    item2Column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);

    MaxWidth = ActualWidth;

    _innerGrid.MinWidth = item1Column.ActualWidth + _item2MinViewableWidth;
    _innerGrid.Width = item1Column.ActualWidth + _item2MinViewableWidth;

    UpdateLayout();

    var mainGridInitWidth = mainGrid.ActualWidth;
    MinWidth = ActualWidth;
    _innerGrid.Width = Double.NaN;

    mainGrid.Width = mainGridInitWidth;
}

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (e.WidthChanged && _innerGrid != null)
    {
        var widthDetla = e.NewSize.Width - e.PreviousSize.Width;
        mainGrid.Width += widthDetla;
    }

    if (Math.Abs(ActualWidth - MaxWidth) < 1)
    {
        dataGrid.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
    }
    else
    {
        dataGrid.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
    }
}

希望这符合您的需求。