1
votes

I have used the style for WPF data grid from this link

I just created a small window with a ViewModel for a datagrid which can be used for data entry.

I have two issues :

  1. If the number of rows is many, the scroll bar does not seem to work when using the vertical scrollbar itself. Scrolling though works if I move the mouse wheel on the datagrid, But if I try the scroll bars, the scrolling does not happen. I saw some samples and they do set the value of scroll bar to Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" I cannot figure out what is wrong here.

  2. When I tab on the WPF grid the focus moves out of the grid. Ideally I want it to create a new row and highlight the first cell in new row to be edited.

Below is the code :

I. View Model :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace SampleAppTest
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {

        public MainWindowViewModel()
        {
            this.Students = new ObservableCollection<Student>();
        }

        private ObservableCollection<Student> students;
        public ObservableCollection<Student> Students
        {
            get
            {
                return this.students;
            }
            set
            {
                this.students = value;
                this.RaisePropertyChanged("Students");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
    }

    public class Student : INotifyPropertyChanged
    {
        private string name;
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
                this.RaisePropertyChanged("Name");
            }
        }

        private int totalMarks;
        public int TotalMarks
        {
            get
            {
                return this.totalMarks;
            }
            set
            {
                this.totalMarks = value;
                this.RaisePropertyChanged("TotalMarks");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
    }
}

II. The Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;

namespace SampleAppTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }
}

III. The XAML

<Window x:Class="SampleAppTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <Style TargetType="DataGrid" x:Key="DefaultDataGridStyle">
                <Setter Property="RowHeaderWidth" Value="0"/>
                <Setter Property="HorizontalGridLinesBrush" Value="Black"/>
                <Setter Property="VerticalGridLinesBrush" Value="Black"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="FontFamily" Value="Segoe UI"/>
                <Setter Property="FontSize" Value="12"/>
                <Setter Property="Background" Value="White"/>
                <Setter Property="BorderBrush" Value="Gray"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="RowBackground" Value="Transparent"/>
                <Setter Property="AlternatingRowBackground" Value="Transparent"/>
                <Setter Property="HeadersVisibility" Value="Column"/>
                <Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
                <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
                <Setter Property="SelectionMode" Value="Single"/>
                <Setter Property="CanUserReorderColumns" Value="False"/>
                <Setter Property="CanUserResizeColumns" Value="True"/>
                <Setter Property="CanUserSortColumns" Value="False"/>
                <Setter Property="AutoGenerateColumns" Value="False"/>
                <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
                <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
                <Setter Property="CanUserAddRows" Value="True"/>
                <Setter Property="DropLocationIndicatorStyle">
                    <Setter.Value>
                        <Style TargetType="Separator">
                            <Setter Property="Background" Value="Gray"/>
                            <Setter Property="Width" Value="2"/>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="Separator">
                                        <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="GridLinesVisibility" Value="None"/>
                <Setter Property="HorizontalGridLinesBrush" Value="Gray"/>
                <Setter Property="IsTabStop" Value="True" />
                <Setter Property="VerticalGridLinesBrush" Value="Gray"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGrid">
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal"/>
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                    <ScrollViewer x:Name="DG_ScrollViewer"
                                          Focusable="false">
                                        <ScrollViewer.Template>
                                            <ControlTemplate TargetType="ScrollViewer">
                                                <Grid x:Name="Root" Background="{TemplateBinding Background}">
                                                    <Grid.Resources>
                                                        <ControlTemplate x:Key="TopLeftHeaderTemplate" TargetType="DataGridColumnHeader">
                                                            <Grid x:Name="Root">
                                                                <Grid.RowDefinitions>
                                                                    <RowDefinition/>
                                                                    <RowDefinition/>
                                                                    <RowDefinition Height="Auto"/>
                                                                </Grid.RowDefinitions>
                                                                <Border BorderBrush="Gray" Background="White" Grid.RowSpan="2"/>
                                                                <Rectangle Fill="Gray" Height="1" Grid.RowSpan="2" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto" Visibility="Collapsed"/>
                                                            </Grid>
                                                        </ControlTemplate>
                                                        <ControlTemplate x:Key="TopRightHeaderTemplate" TargetType="DataGridColumnHeader">
                                                            <Grid x:Name="RootElement">
                                                                <Grid.RowDefinitions>
                                                                    <RowDefinition/>
                                                                    <RowDefinition/>
                                                                    <RowDefinition Height="Auto"/>
                                                                </Grid.RowDefinitions>
                                                                <Border Background="White" Grid.RowSpan="2"/>
                                                            </Grid>
                                                        </ControlTemplate>
                                                    </Grid.Resources>
                                                    <Grid.ColumnDefinitions>
                                                        <ColumnDefinition Width="Auto"/>
                                                        <ColumnDefinition Width="*"/>
                                                        <ColumnDefinition Width="Auto"/>
                                                    </Grid.ColumnDefinitions>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="Auto"/>
                                                        <RowDefinition Height="*"/>
                                                        <RowDefinition Height="Auto"/>
                                                    </Grid.RowDefinitions>
                                                    <DataGridColumnHeader x:Name="TopLeftCornerHeader" Template="{StaticResource TopLeftHeaderTemplate}" Width="0"/>
                                                    <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1"/>
                                                    <DataGridColumnHeader x:Name="TopRightCornerHeader" Grid.Column="2" Template="{StaticResource TopRightHeaderTemplate}"/>
                                                    <Rectangle x:Name="ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" Fill="WhiteSmoke" Height="1" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto" Visibility="Collapsed"/>
                                                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Content="{TemplateBinding Content}" Grid.ColumnSpan="2" Grid.Row="1" CanContentScroll="{TemplateBinding CanContentScroll}" />
                                                    <Rectangle x:Name="BottomRightCorner" Grid.Column="2" Fill="{TemplateBinding Background}" Grid.Row="2"/>
                                                    <Rectangle x:Name="BottomLeftCorner" Grid.ColumnSpan="2" Fill="{TemplateBinding Background}" Grid.Row="2"/>

                                                    <ScrollBar x:Name="PART_VerticalScrollbar" 
                                                       Grid.Column="2" Grid.Row="1"
                                                       Width="18" Margin="0,-1,-3,-1" 
                                                       Orientation="Vertical"
                                                       Maximum="{TemplateBinding ScrollableHeight}"
                                                       ViewportSize="{TemplateBinding ViewportHeight}"
                                                       Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                       Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>

                                                    <Grid Grid.Column="1" Grid.Row="2">
                                                        <Grid.ColumnDefinitions>
                                                            <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
                                                            <ColumnDefinition Width="*"/>
                                                        </Grid.ColumnDefinitions>
                                                        <Rectangle x:Name="FrozenColumnScrollBarSpacer"/>
                                                        <ScrollBar x:Name="PART_HorizontalScrollbar" Grid.Column="1" Height="18" Margin="-1,0,-1,-3" 
                                                           Orientation="Horizontal"
                                                           Maximum="{TemplateBinding ScrollableWidth}"
                                                           ViewportSize="{TemplateBinding ViewportWidth}"
                                                           Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                           Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                                                    </Grid>
                                                </Grid>
                                            </ControlTemplate>
                                        </ScrollViewer.Template>
                                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                    </ScrollViewer>
                                </Border>
                                <Border x:Name="DisabledVisualElement" Background="Gray" CornerRadius="2" HorizontalAlignment="Stretch" Height="Auto" IsHitTestVisible="False" Opacity="0" VerticalAlignment="Stretch" Width="Auto"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBox Margin="10,10,10,10" BorderBrush="Black" Grid.Row="0"></TextBox>
        <DataGrid Grid.Row="1" ItemsSource="{Binding Path=Students}" Style="{StaticResource DefaultDataGridStyle}">
            <DataGrid.Columns>
                <DataGridTextColumn Width="*" Header="Full Name" Binding="{Binding Path=Name}"/>
                <DataGridTextColumn Width="*" Header="Total marks" Binding="{Binding Path=TotalMarks}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Thanks... Girija Shankar

2
I am not able to figure out the issue. Can somebody please tell me what is going wrong here.Shankar

2 Answers

0
votes

if you just want the style and this new Scrolling doesn't really matters to you do this

<ResourceDictionary>
            <Style TargetType="{x:Type DataGrid}" x:Key="DefaultDataGridStyle">
                <Setter Property="RowHeaderWidth" Value="0"/>
                <Setter Property="HorizontalGridLinesBrush" Value="Black"/>
                <Setter Property="VerticalGridLinesBrush" Value="Black"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="FontFamily" Value="Segoe UI"/>
                <Setter Property="FontSize" Value="12"/>
                <Setter Property="Background" Value="White"/>
                <Setter Property="BorderBrush" Value="Gray"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="RowBackground" Value="Transparent"/>
                <Setter Property="AlternatingRowBackground" Value="Transparent"/>
                <Setter Property="HeadersVisibility" Value="Column"/>
                <Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
                <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
                <Setter Property="SelectionMode" Value="Single"/>
                <Setter Property="CanUserReorderColumns" Value="False"/>
                <Setter Property="CanUserResizeColumns" Value="True"/>
                <Setter Property="CanUserSortColumns" Value="False"/>
                <Setter Property="AutoGenerateColumns" Value="False"/>
                <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
                <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
                <Setter Property="CanUserAddRows" Value="True"/>
                <Setter Property="DropLocationIndicatorStyle">
                    <Setter.Value>
                        <Style TargetType="Separator">
                            <Setter Property="Background" Value="Gray"/>
                            <Setter Property="Width" Value="2"/>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="Separator">
                                        <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="GridLinesVisibility" Value="None"/>
                <Setter Property="HorizontalGridLinesBrush" Value="Gray"/>
                <Setter Property="IsTabStop" Value="True" />
                <Setter Property="VerticalGridLinesBrush" Value="Gray"/>
                <!--<Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGrid">
                            <Grid >
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal"/>
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                    <ScrollViewer x:Name="DG_ScrollViewer"
                                          Focusable="false">
                                        <ScrollViewer.Template>
                                            <ControlTemplate TargetType="ScrollViewer">
                                                <Grid x:Name="Root" Background="{TemplateBinding Background}">
                                                    <Grid.Resources>
                                                        <ControlTemplate x:Key="TopLeftHeaderTemplate" TargetType="DataGridColumnHeader">
                                                            <Grid x:Name="Root">
                                                                <Grid.RowDefinitions>
                                                                    <RowDefinition/>
                                                                    <RowDefinition/>
                                                                    <RowDefinition Height="Auto"/>
                                                                </Grid.RowDefinitions>
                                                                <Border BorderBrush="Gray" Background="White" Grid.RowSpan="2"/>
                                                                <Rectangle Fill="Gray" Height="1" Grid.RowSpan="2" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto" Visibility="Collapsed"/>
                                                            </Grid>
                                                        </ControlTemplate>
                                                        <ControlTemplate x:Key="TopRightHeaderTemplate" TargetType="DataGridColumnHeader">
                                                            <Grid x:Name="RootElement">
                                                                <Grid.RowDefinitions>
                                                                    <RowDefinition/>
                                                                    <RowDefinition/>
                                                                    <RowDefinition Height="Auto"/>
                                                                </Grid.RowDefinitions>
                                                                <Border Background="White" Grid.RowSpan="2"/>
                                                            </Grid>
                                                        </ControlTemplate>
                                                    </Grid.Resources>
                                                    <Grid.ColumnDefinitions>
                                                        <ColumnDefinition Width="Auto"/>
                                                        <ColumnDefinition Width="*"/>
                                                        <ColumnDefinition Width="Auto"/>
                                                    </Grid.ColumnDefinitions>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="Auto"/>
                                                        <RowDefinition Height="*"/>
                                                        <RowDefinition Height="Auto"/>
                                                    </Grid.RowDefinitions>
                                                    <DataGridColumnHeader x:Name="TopLeftCornerHeader" Template="{StaticResource TopLeftHeaderTemplate}" Width="0"/>
                                                    <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1"/>
                                                    <DataGridColumnHeader x:Name="TopRightCornerHeader" Grid.Column="2" Template="{StaticResource TopRightHeaderTemplate}"/>
                                                    <Rectangle x:Name="ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" Fill="WhiteSmoke" Height="1" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto" Visibility="Collapsed"/>
                                                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Content="{TemplateBinding Content}" Grid.ColumnSpan="2" Grid.Row="1" CanContentScroll="{TemplateBinding CanContentScroll}" />
                                                    <Rectangle x:Name="BottomRightCorner" Grid.Column="2" Fill="{TemplateBinding Background}" Grid.Row="2"/>
                                                    <Rectangle x:Name="BottomLeftCorner" Grid.ColumnSpan="2" Fill="{TemplateBinding Background}" Grid.Row="2"/>

                                                    <ScrollBar x:Name="PART_VerticalScrollbar" 
                                                       Grid.Column="2" Grid.Row="1"
                                                       Width="18" Margin="0,-1,-3,-1" 
                                                       Orientation="Vertical"
                                                       Maximum="{TemplateBinding ScrollableHeight}"
                                                       ViewportSize="{TemplateBinding ViewportHeight}"
                                                       Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                       Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>

                                                    <Grid Grid.Column="1" Grid.Row="2">
                                                        <Grid.ColumnDefinitions>
                                                            <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
                                                            <ColumnDefinition Width="*"/>
                                                        </Grid.ColumnDefinitions>
                                                        <Rectangle x:Name="FrozenColumnScrollBarSpacer"/>
                                                        <ScrollBar x:Name="PART_HorizontalScrollbar" Grid.Column="1" Height="18" Margin="-1,0,-1,-3" 
                                                           Orientation="Horizontal"
                                                           Maximum="{TemplateBinding ScrollableWidth}"
                                                           ViewportSize="{TemplateBinding ViewportWidth}"
                                                           Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                           Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                                                    </Grid>
                                                </Grid>
                                            </ControlTemplate>
                                        </ScrollViewer.Template>
                                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                    </ScrollViewer>
                                </Border>
                                <Border x:Name="DisabledVisualElement" Background="Gray" CornerRadius="2" HorizontalAlignment="Stretch" Height="Auto" IsHitTestVisible="False" Opacity="0" VerticalAlignment="Stretch" Width="Auto"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>-->
            </Style>
        </ResourceDictionary>

i think the issue is that the DatagridScrollbar already exist and is in use so you got something like

<ScrollViewer> <-- behaves like the inner ScrollViewer because it's binded
    <ScrollViewer/> <-- i think this is "invisible" for you but still enabled and does what it wants because it isn't binded :D
</ScrollViewer>
0
votes

I had the same issue and instead of

 <ScrollBar x:Name="PART_VerticalScrollbar" 
                                                       Grid.Column="2" Grid.Row="1"
                                                       Width="18" Margin="0,-1,-3,-1" 
                                                       Orientation="Vertical"
                                                       Maximum="{TemplateBinding ScrollableHeight}"
                                                       ViewportSize="{TemplateBinding ViewportHeight}"
                                                       Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                       Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>

change your value to Value="{TemplateBinding VerticalOffset}"