Search code examples
c#wpfxamldatagrid

Adjust DataGrid table to window size and use a scroll bar for the data outside of the window size - ScrollBar is never shown


I have created a DataGrid table to present some data and the result is like below:

enter image description here

But as you can see the table is larger than the window size of the application. I would like to either adjust the table size to the window size. I assume this action will cause the table's font to be relatively small. Or a second option would be to use a scroll bar to view the rest of the data grid columns.

Below is the code I used to create the data grid in WPF (.xaml file).

<Window x:Class="TestEnvironment.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestEnvironment"
        mc:Ignorable="d"
        xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        Height="1080" Width="1920" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None">
    <Grid>

        <!--Grid 1-->
        <Grid Height="60" VerticalAlignment="Top" Background="#FF348DE2">
            <TextBlock Text="DQ Tool Loading screen" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" FontFamily="Arial" />
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20 0">
                <Button Content="FAQ" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Content="CONTACT" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Content="MY ACCOUNT" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Name="PowerButton" HorizontalAlignment="Right" VerticalAlignment="Center" Background="{x:Null}" BorderBrush="{x:Null}">
                    <materialDesign:PackIcon Kind="Power"/>
                </Button>
            </StackPanel>
        </Grid>

        <!--Grid 2-->
        <Grid Margin="0 60 0 0">
            <dragablz:TabablzControl SelectionChanged="TabablzControl_SelectionChanged">
                <dragablz:TabablzControl.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF21499A"/>
                        <GradientStop Color="#FF4DB3FA" Offset="1"/>
                    </LinearGradientBrush>
                </dragablz:TabablzControl.BorderBrush>
                <dragablz:TabablzControl.InterTabController>
                    <dragablz:InterTabController/>
                </dragablz:TabablzControl.InterTabController>
                <TabItem Header="LOAD FILES">
                    <Grid x:Name="GridMain" Height="970" Background="LightGray" ShowGridLines="True">
                        <!--Grid Columns-->
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="3*"/>
                        </Grid.ColumnDefinitions>
                        <!--Grid Rows-->
                        <Grid.RowDefinitions>
                            <RowDefinition Height="40" />
                            <RowDefinition Height="40" />
                            <RowDefinition Height="6*" />

                        </Grid.RowDefinitions>

                        <TextBox HorizontalAlignment="Left" 
                                 Height="40"
                                 Text="File Path imported"
                                 FontStyle="Italic"
                                 FontFamily="Arial"  
                                 VerticalAlignment="Top"
                                 Name="FileNameTextBox"
                                 Grid.Column="1"
                                 Grid.Row="1"/>
                        <Button x:Name="BrowseButton" 
                                Content="Browse a file" 
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top" 
                                Width="120" 
                                Click="BrowseButton_Click" 
                                RenderTransformOrigin="1.047,0.821" 
                                Height="40"
                                Grid.Column="2"
                                Grid.Row="1"/>
                        <TextBlock HorizontalAlignment="Left" 
                                   Height="40"
                                   Text="TextBlock" 
                                   FontFamily="Arial"
                                   VerticalAlignment="Top"
                                   Name="TextBlock1"
                                   Grid.Column="1"
                                   Grid.Row="2"
                                   Grid.RowSpan="2"
                                   Grid.ColumnSpan="2"/>
                        <DataGrid Name="grid"
                                  ItemsSource="{Binding}"
                                  HorizontalAlignment="Stretch"
                                  VerticalAlignment="Top"
                                  CanUserResizeRows="False"
                                  IsReadOnly="True"
                                  Grid.Column="1"
                                  Grid.Row="2"
                                  Grid.ColumnSpan="2">
                        </DataGrid>
                        <Button x:Name="LoadButton"
                                Content="Load"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Top" 
                                Width="120" 
                                Click="BrowseButton_Click" 
                                RenderTransformOrigin="1.047,0.821" 
                                Height="40"
                                Grid.Column="4"
                                Grid.Row="1"/>
                    </Grid>
                </TabItem>
                <TabItem Header="FILES LAYOUT">
                    <TextBlock Text="Amazing designs!" Background="LightGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </TabItem>
                <TabItem Header="BUSINESS CHECKS">
                    <TextBlock Text="Ask for any question!" Background="LightGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </TabItem>
                
            </dragablz:TabablzControl>
        </Grid>
    </Grid>
</Window>

The .cs file I use to bind the data grid to the content of a txt file.

using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Data;
using System.IO;

namespace TestEnvironment
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public DataTable ConvertToDataTable(string filePath)
        {
            DataTable tbl = new DataTable();

            // Take the first 10 lines
            var lines = File.ReadLines(filePath).Take(10);

            // Split each line and create an integer sequence where each value 
            // is the number of the splitted elements
            // then get the max value present in this sequence
            var max = lines.Select(x => x.Split('\t').Length).Max();

            // First line contains headers
            string[] headers = lines.First().Split('\t');

            // Now create the table with the max number of columns present
            for (int col = 0; col < max; col++)
                tbl.Columns.Add(new DataColumn(headers[col]));

            //Use the Rows.Add method that accepts an object array
            foreach (string line in lines.Skip(1))
            {
                tbl.Rows.Add(line.Split('\t'));
            }
            return tbl;
        }

        public static void WriteDataToFile(DataTable submittedDataTable, string submittedFilePath)
        {
            int i = 0;
            StreamWriter sw = null;

            sw = new StreamWriter(submittedFilePath, false);

            for (i = 0; i < submittedDataTable.Columns.Count - 1; i++)
            {

                sw.Write(submittedDataTable.Columns[i].ColumnName + ";");

            }
            sw.Write(submittedDataTable.Columns[i].ColumnName);
            sw.WriteLine();

            foreach (DataRow row in submittedDataTable.Rows)
            {
                object[] array = row.ItemArray;

                for (i = 0; i < array.Length - 1; i++)
                {
                    sw.Write(array[i].ToString() + ";");
                }
                sw.Write(array[i].ToString());
                sw.WriteLine();

            }

            sw.Close();
        }

        private void BrowseButton_Click(object sender, RoutedEventArgs e)
        {   

            // Create OpenFileDialog
            Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();

            // Launch OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = openFileDlg.ShowDialog();
            // Get the selected file name and display in a TextBox.
            // Load content of file in a TextBlock
            if (result == true)
            {
                FileNameTextBox.Text = openFileDlg.FileName;
                TextBlock1.Text = "Created on: " + File.GetCreationTime(openFileDlg.FileName).ToString() +"\n";
                
                Debug.WriteLine(File.GetCreationTime(openFileDlg.FileName).ToString());
                
                var datatablematrix = ConvertToDataTable(filePath: openFileDlg.FileName);

                /*Debug.WriteLine(datatablematrix);

                WriteDataToFile(datatablematrix, @"C:\Users\spano\Desktop\ApplicationOption2\testdummy.txt");*/

                grid.DataContext = datatablematrix.DefaultView;

            }

            // Set filter for file extension and default file extension  
            openFileDlg.DefaultExt = ".txt";
            openFileDlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";

            Debug.WriteLine("Txt imported");

            // Set initial directory    
            openFileDlg.InitialDirectory = @"C:\Documents\";

            // Multiple selection with all file types    
            openFileDlg.Multiselect = true;

            Debug.WriteLine("End!");

        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)

        {

            // this.Close();

            App.Current.Shutdown();

        }

        private void TabablzControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
}

I attach also the app.xaml file in case you want to replicate the issue on your local machine

Custom nuget packages used: dragablz, MaterialDesignThemes

<Application x:Class="TestEnvironment.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestEnvironment"
             xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!-- primary color -->
                <ResourceDictionary>
                    <!-- include your primary palette -->
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.blue.xaml" /> <!--blue instead of purple-->
                    </ResourceDictionary.MergedDictionaries>

                    <!--
                            include three hues from the primary palette (and the associated forecolours).
                            Do not rename, keep in sequence; light to dark.
                        -->
                    <SolidColorBrush x:Key="PrimaryHueLightBrush" Color="{StaticResource Primary100}"/>
                    <SolidColorBrush x:Key="PrimaryHueLightForegroundBrush" Color="{StaticResource Primary100Foreground}"/>
                    <SolidColorBrush x:Key="PrimaryHueMidBrush" Color="{StaticResource Primary500}"/>
                    <SolidColorBrush x:Key="PrimaryHueMidForegroundBrush" Color="{StaticResource Primary500Foreground}"/>
                    <SolidColorBrush x:Key="PrimaryHueDarkBrush" Color="{StaticResource Primary500}"/>
                    <SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush" Color="{StaticResource Primary700Foreground}"/>
                </ResourceDictionary>

                <!-- secondary colour -->
                <ResourceDictionary>
                    <!-- include your secondary pallette -->
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.blue.xaml" />  <!--blue instead of purple-->
                    </ResourceDictionary.MergedDictionaries>

                    <!-- include a single secondary accent color (and the associated forecolour) -->
                    <SolidColorBrush x:Key="SecondaryAccentBrush" Color="{StaticResource Accent100}"/>
                    <SolidColorBrush x:Key="SecondaryAccentForegroundBrush" Color="{StaticResource Accent200Foreground}"/>
                </ResourceDictionary>

                <!-- Include the Dragablz Material Design style -->
                <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
            </ResourceDictionary.MergedDictionaries>

            <!-- tell Dragablz tab control to use the Material Design theme -->
            <Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}" />
        </ResourceDictionary>
    </Application.Resources>
</Application>

A dummy txt file with similar data can be found here

UPDATE Based on some online research

I have added the option of viewing the scrollbar of the data based on this article

<DataGrid Name="grid"
                                  ItemsSource="{Binding}"
                                  HorizontalAlignment="Left"
                                  VerticalAlignment="Stretch"
                                  VerticalScrollBarVisibility="Visible"
                                  HorizontalScrollBarVisibility="Visible"
                                  ScrollViewer.VerticalScrollBarVisibility="Visible"
                                  ScrollViewer.HorizontalScrollBarVisibility="Visible"
                                  CanUserResizeRows="False"
                                  IsReadOnly="True"
                                  Height="800"
                                  Width="1300"
                                  Grid.Column="1"
                                  Grid.Row="2"
                                  Grid.ColumnSpan="2">
                        </DataGrid>

In .cs file:

        private void EnableScrollBars()
        {
            ScrollViewer.SetHorizontalScrollBarVisibility(this.grid, ScrollBarVisibility.Visible);
            ScrollViewer.SetVerticalScrollBarVisibility(this.grid, ScrollBarVisibility.Visible);
        }

However, the result is still the same. Nothing is shown in my application. Also my window size is 1080x1920

enter image description here

Any thoughts if this is a bug of DataGrid?

[UDPATE 2: Based on this question

<Window x:Class="TestEnvironment.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestEnvironment"
        mc:Ignorable="d"
        xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        Height="1080" Width="1920" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None">
    <Grid>

        <!--Grid 1-->
        <Grid Height="60" VerticalAlignment="Top" Background="#FF348DE2">
            <TextBlock Text="DQ Tool Loading screen" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" FontFamily="Arial" />
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20 0">
                <Button Content="FAQ" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Content="CONTACT" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Content="MY ACCOUNT" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
                <Button Name="MinimizeButton" HorizontalAlignment="Right" VerticalAlignment="Center" Background="{x:Null}" BorderBrush="{x:Null}" Click="MinimizeButton_Click">
                    <materialDesign:PackIcon Kind="WindowMinimize"/>
                </Button>
                <Button Name="PowerButton" HorizontalAlignment="Right" VerticalAlignment="Center" Background="{x:Null}" BorderBrush="{x:Null}" Click="PowerButton_Click">
                    <materialDesign:PackIcon Kind="ExitToApp"/>
                </Button>
            </StackPanel>
        </Grid>

        <!--Grid 2-->
        <Grid Margin="0 60 0 0">
            <dragablz:TabablzControl SelectionChanged="TabablzControl_SelectionChanged">
                <dragablz:TabablzControl.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF21499A"/>
                        <GradientStop Color="#FF4DB3FA" Offset="1"/>
                    </LinearGradientBrush>
                </dragablz:TabablzControl.BorderBrush>
                <dragablz:TabablzControl.InterTabController>
                    <dragablz:InterTabController/>
                </dragablz:TabablzControl.InterTabController>
                <TabItem Header="LOAD FILES">
                    <Grid x:Name="GridMain" Height="970" Background="LightGray" ShowGridLines="True">
                        <!--Grid Columns-->
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="3*"/>
                        </Grid.ColumnDefinitions>
                        <!--Grid Rows-->
                        <Grid.RowDefinitions>
                            <RowDefinition Height="40" />
                            <RowDefinition Height="40" />
                            <RowDefinition Height="6*" />

                        </Grid.RowDefinitions>

                        <TextBox HorizontalAlignment="Left" 
                                 Height="40"
                                 Text="File Path imported"
                                 FontStyle="Italic"
                                 FontFamily="Arial"  
                                 VerticalAlignment="Top"
                                 Name="FileNameTextBox"
                                 Grid.Column="1"
                                 Grid.Row="1"/>
                        <Button x:Name="BrowseButton" 
                                Content="Browse a file" 
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top" 
                                Width="120" 
                                Click="BrowseButton_Click" 
                                RenderTransformOrigin="1.047,0.821" 
                                Height="40"
                                Grid.Column="2"
                                Grid.Row="1"/>
                        <TextBlock HorizontalAlignment="Left" 
                                   Height="40"
                                   Text="TextBlock" 
                                   FontFamily="Arial"
                                   VerticalAlignment="Top"
                                   Name="TextBlock1"
                                   Grid.Column="1"
                                   Grid.Row="2"
                                   Grid.RowSpan="2"
                                   Grid.ColumnSpan="2"/>
                        <!--
                        <DockPanel Grid.Row="2"
                                   Grid.Column="1"
                                   Grid.ColumnSpan="2"
                                   VerticalAlignment="Stretch"
                                   HorizontalAlignment="Stretch">
                            <DataGrid x:Name="grid" 
                                      VerticalAlignment="Stretch" 
                                      ItemsSource="{Binding}"
                                      CanUserResizeRows="False"
                                      IsReadOnly="True"
                                      MinHeight="100" 
                                      SelectionMode="Single" 
                                      AutoGenerateColumns="False" 
                                      VerticalScrollBarVisibility="Visible"
                                      HorizontalScrollBarVisibility="Auto">
                            </DataGrid>
                        </DockPanel>
                        -->
                        <Border BorderBrush="Black" 
                                BorderThickness="3"
                                ScrollViewer.VerticalScrollBarVisibility="Visible"
                                ScrollViewer.HorizontalScrollBarVisibility="Visible"
                                Grid.Column="1"
                                Grid.Row="2"
                                Grid.ColumnSpan="2"
                                Width="1300"
                                Height="800"
                                HorizontalAlignment="Left">
                            <DataGrid Name="grid"
                                  ItemsSource="{Binding}"
                                  HorizontalAlignment="Left"
                                  VerticalAlignment="Stretch"
                                  VerticalScrollBarVisibility="Auto"
                                  HorizontalScrollBarVisibility="Auto"
                                  ScrollViewer.VerticalScrollBarVisibility="Visible"
                                  ScrollViewer.HorizontalScrollBarVisibility="Visible"
                                  CanUserResizeRows="False"
                                  IsReadOnly="True"
                                  Height="800"
                                  Width="1300"
                                  Grid.Column="1"
                                  Grid.Row="2"
                                  Grid.ColumnSpan="2">
                            </DataGrid>
                        </Border>
                        <Button x:Name="LoadButton"
                                Content="Load"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Top" 
                                Width="120" 
                                Click="BrowseButton_Click" 
                                RenderTransformOrigin="1.047,0.821" 
                                Height="40"
                                Grid.Column="3"
                                Grid.Row="1"/>
                    </Grid>
                </TabItem>
                <TabItem Header="FILES LAYOUT">
                    <TextBlock Text="Amazing designs!" Background="LightGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </TabItem>
                <TabItem Header="BUSINESS CHECKS">
                    <TextBlock Text="Ask for any question!" Background="LightGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </TabItem>
                
            </dragablz:TabablzControl>
        </Grid>
    </Grid>
</Window>

Output

enter image description here

Still nothing related to a vertical or horizontal scrollbar is shown


Solution

  • You missed to merge MaterialDesign color theme into your ResourceDictionary.

    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
    
      <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Dark.xaml" />
    </ResourceDictionary.MergedDictionaries>
    

    You can see more details in this SO answer: https://stackoverflow.com/a/62667182/2458980