2

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 http://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>
0

3 Answers 3

4

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?

Sign up to request clarification or add additional context in comments.

5 Comments

Ok it works how I want but what if I have DataGrid rendered in UserControl? Width="{Binding ElementName=ShellView, Path=ActualWidth}" in UserControl doesn't work for me.
Glad it works. Feel free to vote up helpful answes or mark one as the answer. You will have to show me how you using that UserControl. How does the xaml of that usercontrol looks like?
It's little bit complicated because I use Caliburn.Micro which I'm learning ;). I have <ContentControl x:Name="MyUserControlWithGrid" /> which display my UserControl and their I try to get window1 or ShellView in my case.
You can change binding to this: Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth}" It a small trick letting the control find first parent of type usercontrol. You will have a custom usercontrol but it will inherit from usercontrol itself and it will work. I hope the first parent of type usercontrol is the one you wish to be used.
In my case I needed to change x:Type UserControl to x:Type Window . Anyway if I run my sample project scrollbar is shown always even if whole content is visible. Could you check my edited sample.
0

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;
    }

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.