我在DataGrid
中有一个ScrollViewer
。我有两个问题之一:
缩小宽度并且剪切掉项目文本(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>
当我有一个可以使用的滚动条时,可以调整列的大小,以便右侧的视图不可见(中心分隔线可以向右移动足够远,以至于整个列都不可见)。 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)相同。
我还注意到,当垂直内容被切掉并且垂直滚动条出现(同时出现)时,滚动条的确出现了(两个实例)。有没有建议使用滚动条并能够确保列不会离开屏幕?
答案 0 :(得分:1)
问题是DataGrid的宽度绑定到ScrollViewer的宽度
<DataGrid Width={Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}">
DataGrid永远不会比ScrollViewer宽,因此不会启用滚动条。
将HorizontalAlignment设置为“ 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;
}
}
希望这符合您的需求。