简体   繁体   中英

WPF: Resize width of datagrid inside ScrollViewer

I have ScrollViewer where is displayed page content. Inside I have a DataGrid, but when I put DataGrid inside ScrollViewer width of columns is lost. So I readed here h ttp://stackoverflow.com/questions/17875765/wpf-scrollviewer-around-datagrid-affects-column-width that I need to bind width of parent to my DataGrid and it's ok but what's the problem. When width of window is increase width of DataGrid is increased too but when width of window is decreased width of DataGrid doesn't change. What I would like to have is when width of is change width of DataGrid is changed too.

This is sample XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <!--Page Content-->
        <Grid x:Name="grid">
            <DataGrid Width="{Binding ElementName=grid, Path=ActualWidth}">
                <DataGrid.Columns>
                    <DataGridTextColumn Width="*" Header="Header 1"  />
                    <DataGridTextColumn Width="*" Header="Header 2" /> 
                    <DataGridTextColumn Width="*" Header="Header 3" /> 
                    <DataGridTextColumn Width="*" Header="Header 4" />
                    <DataGridTextColumn Width="*" Header="Header 5" />
                    <DataGridTextColumn Width="*" Header="Header 6" />
                    <DataGridTextColumn Width="*" Header="Header 7" /> 
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </ScrollViewer>
</Window>

EDITED: Now my MainWindow looks like:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:my="clr-namespace:WpfApplication1"
        x:Name="window1">
    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
        <my:MyGrid />
    </ScrollViewer>
</Window>

and my control:

<UserControl x:Class="WpfApplication1.MyGrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <DataGrid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=ActualWidth}">
            <DataGrid.Columns>
                <DataGridTextColumn Width="*" Header="Header 1"  />
                <DataGridTextColumn Width="*" Header="Header 2" />
                <DataGridTextColumn Width="*" Header="Header 3" />
                <DataGridTextColumn Width="*" Header="Header 4" />
                <DataGridTextColumn Width="*" Header="Header 5" />
                <DataGridTextColumn Width="*" Header="Header 6" />
                <DataGridTextColumn Width="*" Header="Header 7" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

Try this approach:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        x:Name="window1">
    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <!--Page Content-->
            <DataGrid Width="{Binding ElementName=window1, Path=ActualWidth}">
                <DataGrid.Columns>
                    <DataGridTextColumn Width="*" Header="Header 1"  />
                    <DataGridTextColumn Width="*" Header="Header 2" /> 
                    <DataGridTextColumn Width="*" Header="Header 3" /> 
                    <DataGridTextColumn Width="*" Header="Header 4" />
                    <DataGridTextColumn Width="*" Header="Header 5" />
                    <DataGridTextColumn Width="*" Header="Header 6" />
                    <DataGridTextColumn Width="*" Header="Header 7" /> 
                </DataGrid.Columns>
            </DataGrid>
    </ScrollViewer>
</Window>

Would this suit you better?

The above solution almost worked for me, except there was extra scrollbars (the inner ones from DataGrid, and the outer ones from ScrollViewer). The inner ones had been hidden before because Window.ActualWidth and ActualHeight are a little too big. The DataGrid's size needs to be a little less then the Window's size, because of the Window's outside border. A Converter can be used to subtract off 25 from the width, and 42 from the height.

My working solution ended up being code-based. Sorry, I realize everyone works in xaml. But I'll post it in case anyone else is curious how to do the same thing in code...

class FindResultsGrid : Window
{
    public FindResultsGrid(List<FindResultLine> list)
    {
        var dg = new DataGrid() 
        { 
            AutoGenerateColumns = false, 
            Height = 450, // starting size, will be dynamic based on window...
            Width = 900,
            SelectionMode= DataGridSelectionMode.Single 
        };
        this.Width = dg.Width + 25;
        this.Height = dg.Height + 42;

        dg.AddColumn("Item", "ItemName", width: 151);
        dg.AddColumn("Line #", "lineNbr", width: 51);
        dg.AddColumn("Text", "lineText");

        dg.SetBinding(DataGrid.WidthProperty, new Binding("ActualWidth") { Source = this, Converter=new WidthConversion() });
        dg.SetBinding(DataGrid.HeightProperty, new Binding("ActualHeight") { Source = this, Converter=new HeightConversion() });

        this.Content = dg;

        dg.ItemsSource = list;
    }
}
class WidthConversion : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((double)value) - 25.0;
    }
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); }
}
class HeightConversion : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((double)value) - 42;
    }
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); }
}


public static class MyExtensions
{
    public static DataGridTextColumn AddColumn(this DataGrid dg, string header,
        string propertyPath = null,
        double width = Double.NaN,
        BindingMode way = BindingMode.OneWay,
        bool canUserSort = true)
    {
        if (propertyPath == null)
            propertyPath = header;
        var binding = new System.Windows.Data.Binding(propertyPath);
        binding.Mode = way;
        var col = new DataGridTextColumn()
        {
            Header = header,
            Binding = binding,
            Width = Double.IsNaN(width) ? DataGridLength.Auto : new DataGridLength(width),
            CanUserSort = canUserSort
        };
        dg.Columns.Add(col);
        return col;
    }

Try this: I was also having the same issue when using datagrid along with scrollviewer. Set HorizontalScrollBarVisibility property for the ScrollViewer equal to 'Disabled'. It works when the width is increased and also when it is decreased.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM