binding datagrid column to selecteditem property - c#

I have a datagrid where if a row is clicked upon the row details is shown. In the row details is another datagrid called dgRights.
So dgRights is bound to SelectItem.Funds where funds is a custom list. dgRights show 4 columns, 3 of which are bound fine however the fourth isn't (in my code below its called "Rights Sedol").
I want the column Rights Sedol to be bound to a property of the selectedItem not selectedItem.Funds, is this possible?
I've tried the lines of code below without luck,
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}/>
2nd
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=DataGrid}}/>
I also tried changing the ItemSource of the datagrid from SelectedItem.Funds to just SelectItem & changed the other 3 working columns to Funds.Code etc but this didn't display any data in the datagrid at all. So not sure what to do?
App.xaml - my row details data template
<DataTemplate x:Key="DG_RowDetailRGHTSHist">
<Grid x:Name="RowDetailGrid"
Margin="5"
HorizontalAlignment="Left">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="250"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="5,5,5,5"
HorizontalAlignment="Left"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
Text="Fund Summary">
</TextBlock>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
ItemsSource="{Binding SelectedItem.Funds, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
RowStyle="{StaticResource DG_Row}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeader}"
RowHeaderStyle="{StaticResource DG_RowHeaderNested}"
CellStyle="{StaticResource DG_Cell}"
Background="Silver"
HorizontalGridLinesBrush="LightGray"
VerticalGridLinesBrush="LightGray"
CanUserAddRows="False"
CanUserDeleteRows="False"
Margin="50,5,5,20"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Fund Code" Binding="{Binding Code}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Fund Code SS" Binding="{Binding CodeSS}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Number of Rights" Binding="{Binding CurrentNominal, Mode=TwoWay, StringFormat={}{0:N0}}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Border>
</Grid>
</DataTemplate>

You want to access the 2nd datagrid up so you need to specify AncestorLevel=2.
{RelativeSource AncestorType=DataGrid, AncestorLevel=2}}

Related

WPF Datagrid showing extra column

My grid is showing an extra column.
Can someone help me please? I have two columns. Document name and document date. What is the third column that is showing up? The datasource has four properties. I need 2 of them.
Also, When the grid first loads how do I highlight the first row
<Grid VerticalAlignment="Stretch" Focusable="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" ></ColumnDefinition>
<ColumnDefinition Width="6"></ColumnDefinition>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" Grid.RowSpan="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"
BorderBrush="DarkSlateGray" BorderThickness="1" Width="6" ShowsPreview="True" >
<GridSplitter.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FF808385" Offset="0"/>
<GradientStop Color="#FFECF1F7" Offset="1"/>
</LinearGradientBrush>
</GridSplitter.Background>
</GridSplitter>
<ScrollViewer Name="scrollViewer" PreviewMouseWheel="ScrollViewer_OnPreviewMouseWheel">
<DataGrid Name = "dataGrid"
SelectionChanged="ShowDocument" AutoGenerateColumns="False"
PreviewMouseWheel="DataGrid_PreviewMouseWheel" >
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header = "Document Name" Binding = "{Binding Name, Mode=OneWay}" SortMemberPath="Name" />
<DataGridTextColumn Header = "Document Date" Binding = "{Binding DocumentDate, StringFormat=\{0:d\}, Mode=OneWay}" SortMemberPath="DocumentDate" />
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
Seems like you need to allow second column in your grid to use the remaining space like so:
<DataGridTextColumn Binding="{Binding DocumentDate, StringFormat=\{0:d\}, Mode=OneWay}"
Header="Document Date"
Width="*"
SortMemberPath="DocumentDate" />
See also: https://stackoverflow.com/a/5028932/7127128
Also you can select the first line by setting selected index in DataGrid:
<DataGrid Name = "dataGrid"
...
SelectedIndex="0"
...>

WPF Datagrid not taking up all available remaining space

I have a WPF DataGrid and no matter what I try it won't resize to fit the available space. In my Window there is a lot of empty space to the right and I want the columns to change their width according to the space available.
The code I have for the Datagrid is:
<DataGrid x:Name="ResultDataGrid" Margin="40,30,6,6" Grid.Row="1" ScrollViewer.CanContentScroll="True" AutoGenerateColumns="False" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
ItemsSource="{Binding Records}" Background="Transparent" HeadersVisibility="Column" IsReadOnly="true" CanUserSortColumns="False" LostFocus="ResultDataGrid_LostFocus" HorizontalAlignment="Left" VerticalAlignment="Top">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<EventSetter Event="Click" Handler="ColumnHeader_Click" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox VerticalAlignment="Center" IsChecked="{Binding Path=IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_Click"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn x:Name="DeviceSNDataGridText" Binding="{Binding InsCCode}"
Header="{StaticResource DeviceSNString}" FontSize="14"/>
<DataGridTextColumn x:Name="DataTimeDataGridText" Binding="{Binding Created}"
Header="{StaticResource DateTimeString}"/>
<DataGridTextColumn x:Name="ModeDataGridText" Binding="{Binding Mode}"
Header="{StaticResource ModeString}" FontSize="14" />
<DataGridTextColumn x:Name="ResultDataGridText" Binding="{Binding Result}"
Header="{StaticResource ResultString}" FontSize="14" />
<DataGridTextColumn x:Name="ScanIndexDataGridText" Binding="{Binding ScanIndex}"
Header="{StaticResource ScanIndexString}" FontSize="14" />
</DataGrid.Columns>
</DataGrid>
After reading online, I tried setting each DataGridTextColumn width to * but that gave me this resulting datagrid below:
I also tried setting the ColumnWidth on the Datagrid itself to * but it also gave the same result as the picture above.
By the way, my datagrid is contained within a grid (on Row 1) which is defined like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="50"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
What am I missing? Any suggestions please?

binding to datepicker in datagrid rowdetails

I have a datagrid. When a row is click on the rowdetails is shown. In the rowdetails I have another datagrid next to the datagrid is a DatePicker.
So the main datagrid has a collection of a custom object. When a row is clicked the sub datagrid is bound to the selecteditem.Funds (another list) (code shown below). The selectedItem also has a datetime property which I want to bind to my DatePicker however I cannot get it to work.
I am using the line below,
<DatePicker SelectedDate="{Binding SelectedItem.DateEffective2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
I assumed (maybe wrongly that because the datepicker is in the rowdetails I would be able to bind to the selectedItem, guess I'm wrong?
<DataGrid Grid.Row="1"
ItemsSource="{Binding HldLogEQCurr, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedHldLogEq, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource DataGridTemplate1}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeaderCenter1}"
RowStyle="{StaticResource DG_Row1}"
CellStyle="{StaticResource DG_Cell1}"
RowHeaderStyle="{StaticResource DG_RowHeader1}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
Background="Silver"
Margin="50,50,50,50"
CanUserDeleteRows="False"
CanUserAddRows="False"
RowHeaderWidth="30">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Grid x:Name="RowDetailGrid"
Margin="5"
HorizontalAlignment="Left">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="250"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="5,5,5,5"
HorizontalAlignment="Left"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
Text="Select action to take">
</TextBlock>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
ItemsSource="{Binding SelectedItem.Funds, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
RowStyle="{StaticResource DG_Row}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeader}"
RowHeaderStyle="{StaticResource DG_RowHeaderNested}"
CellStyle="{StaticResource DG_Cell}"
Background="Silver"
HorizontalGridLinesBrush="LightGray"
VerticalGridLinesBrush="LightGray"
CanUserAddRows="False"
CanUserDeleteRows="False"
Margin="50,5,5,20"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Fund Code" Binding="{Binding Code}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Fund Code SS" Binding="{Binding CodeSS}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Number of Rights" Binding="{Binding CurrentNominal, StringFormat={}{0:N0}}" IsReadOnly="True"/>
<DataGridTextColumn Header="Rights To Exercise" Binding="{Binding NewNominal, StringFormat={}{0:N0}}" IsReadOnly="True"/>
<DataGridCheckBoxColumn Header="Take Cash" Binding="{Binding OptionOne, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False"/>
<DataGridCheckBoxColumn Header="Take Stock" Binding="{Binding OptionTwo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False"/>
<DataGridCheckBoxColumn Header="Take Both" Binding="{Binding OptionThree, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False"/>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Column="2" Grid.Row="0" Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Grid.Column="2" Margin="20,0,0,0">
<TextBlock Margin="0,5,5,5" HorizontalAlignment="Left" FontSize="12" FontWeight="Bold" Foreground="Black"
Text="Select Date Effective From"/>
<DatePicker HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,10,0,0"
BorderThickness="0" SelectedDate="{Binding SelectedItem.DateEffective, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200"/>
</StackPanel>
</Grid>
</Grid>
</Border>
</Grid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.Columns>
<DataGridTextColumn Header="Date Entered" IsReadOnly="True" Binding="{Binding DateEntered, StringFormat={}\{0:dd-MMM-yy\}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="75"/>
<DataGridTextColumn Header="Date Effective" IsReadOnly="True" Binding="{Binding DateEffective, StringFormat={}\{0:dd-MMM-yy\}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="75"/>
<DataGridTextColumn Header="Sedol" IsReadOnly="True" Binding="{Binding Security.Sedol}" MinWidth="75"/>
<DataGridTextColumn Header="Name" IsReadOnly="True" Binding="{Binding Security.Name}" MinWidth="200"/>
<DataGridTextColumn Header="Ratio" IsReadOnly="True" Binding="{Binding RatioNew}" MinWidth="75"/>
</DataGrid.Columns>
</DataGrid>
The DataContext for the DatePicker should already be the SelectedItem, try changing it to:
<DatePicker SelectedDate="{Binding DateEffective2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Also, your sub-DataGrid's ItemsSource could be simplified from:
ItemsSource="{Binding SelectedItem.Funds, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
To:
ItemsSource="{Binding Funds}"

Application Resolution Issue

This is something that I have been skipping and leaving till the end because I can't seem to find the answer and ive looked for so long.
I have a an application inside a Window, and I have built the Application to my screens resolution which is 1600 x 900. If I run the application on a screen with a resolution of 1024 x 768 my whole interface will not scale down.
Example.
Now I know alot of you will be thinking to add Dockpanels etc ... But I have tried to do this. When you change the Resolutions it doesn't work it just fixes the object to one place.
What I want to happen.
If any of you know the solution to this annoying problem, please let me know.
I dont know much about resolutions, only what I have done hours of research on.
EDIT1
Here is some of my XAML:
<DockPanel HorizontalAlignment="Left" Height="236" LastChildFill="False" Margin="380,150,0,0" VerticalAlignment="Top" Width="792">
<DataGrid x:Name="dgFake" VerticalAlignment="Center" Height="236" ItemsSource="{Binding}" Foreground="#FF474747" BorderBrush="#FFBDBDBD" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}" CanUserResizeRows="False" ScrollViewer.CanContentScroll="True" Background="#FFEEFAFF" RowBackground="#FFEEFAFF" RowHeaderWidth="0" RowHeight="25" AutoGenerateColumns="False" Width="792" DockPanel.Dock="Left" FontSize="16" TextBlock.TextAlignment="Center" HorizontalContentAlignment="Stretch" SelectionChanged="dgFake_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FFF}" Header="FFF" Visibility="Hidden" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*" />
<DataGridTextColumn Binding="{Binding EEE}" Header="EEE" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*" />
<DataGridTextColumn Binding="{Binding GGG}" Header="GGG" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding CCC}" Header="CCC" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding BBB}" Header="BBB" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding AAA}" Header="AAA" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding DDD}" Header="DDD" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" TextBlock.TextAlignment="Center" Width="*"/>
</DataGrid.Columns>
<Label x:Name="lblView" Content="Select View ..." HorizontalAlignment="Left" Margin="380,109,0,0" VerticalAlignment="Top" Foreground="#FF474747"/>
<ComboBox x:Name="cmbViews" HorizontalAlignment="Left" Margin="380,124,0,0" VerticalAlignment="Top" Width="162" Text="Select ..." SelectionChanged="cmbView">
<ComboBoxItem Content="Company" Foreground="#FFA2A2A2"/>
<ComboBoxItem Content="Employee" Foreground="#FFA2A2A2"/>
</ComboBox>
I suspect that you have basically designed your WPF application as if it were a WinForms application, setting exact Height and Width values on your UI elements. That is not how we layout UI elements in WPF. If you did do that, then you are correct that putting them in a DockPanel will not fix your problem.
In WPF, we generally use Grid elements to make full use of the available space provided to them. Setting a Grid.ColumnDefinition.Width to Auto and another to * will fill *all of the available width:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <!-- Just big enough for content -->
<ColumnDefinition Width="*" /> <!-- Fills all remaining space -->
</Grid.ColumnDefinitions>
...
<TextBlock Grid.Column="1" Text="I'm in the right cell" />
That's just one example of many... Please read through the Introduction to WPF Layout page from the WPF Tutorial.net website for more information.
The problem you describe is actually quite easy to solve, you simply NEVER use a fixed size for anything. All your panels have to be sized relative to something.
Changing the resolution of a screen is literally the same as changing the size of your window. If it works with a Window.Size of 1024x768 it will work at a 1024x768 resolution.
<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="384" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<!-- Pretend I'm a logo -->
<Border Height="23" Width="75" HorizontalAlignment="Left" Background="Blue" CornerRadius="5" Padding="3">
<TextBlock Foreground="White">Logo</TextBlock>
</Border>
<WrapPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Text="About" Margin="6"/>
<TextBlock Text="Home" Margin="6"/>
<TextBlock Text="Help" Margin="6"/>
<TextBlock Text="Settings" Margin="6"/>
</WrapPanel>
<ListBox Grid.Row="1" Grid.Column="0"
BorderThickness="0">
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
</ListBox>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border >
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Red" />
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock>I'm a Data Grid</TextBlock>
</Border>
<GridSplitter Grid.Row="1" VerticalAlignment="Top" Height="3"/>
<Border Grid.Row="1" Margin="0,3,0,0">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Blue" />
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock>I'm a Data Grid</TextBlock>
</Border>
</Grid>
</Grid>
</Window>
The gradients are there so you can see its working when you resize.
If you've already designed to a fixed resolution then an easy hack is to wrap everything in a ViewBox and give the encapsulating child the same dimensions as the resolution you designed for. So if you designed for 1600 x 900 and your main window contained this:
<Grid>
<TextBlock Text="Big Text" FontSize="100" />
</Grid>
...then replace it with this:
<Viewbox Stretch="Uniform">
<Grid Width="1600" Height="900">
<TextBlock Text="Big Text" FontSize="100" />
</Grid>
</Viewbox>
Then make a mental note to do your UI design properly from day 1 next time.

Horizontal Scrolling Issue

I'm new to WPF and I'm trying to create an dashboard interface for an app I'm developing. My problem is as follows;
I have a datagrid which will contain my data. This datagrid is inside a grid because I needed superheaders over particular sections. I inserted a test row into the data table and it shows up fine, but the datagrid element inside the grid seems to have its own scrollbar. Both the super header row and the datagrid row extend off the window but only the datagrid row scrolls. The 2 visible super headers stay in the same place while the datagrid row scrolls. Below is my xaml code to generate the interface. I have tried wrapping the grid in a scrollviewer and also setting the horizontal scrollbar of the row with the super headers to visible but nothing has worked so far. If I can get the super headers to scroll at all at least I can try to make an event handler to move the super headers when the datagrid scrollbar is moved. Sorry if this seems kinda garbled but I haven't had my coffee yet and I also have a migraine, 2 of the best things for a programmer to experience.
Thanks in advance
<Canvas HorizontalAlignment="Center" Height="508" VerticalAlignment="Top" Width="1366" Margin="-4,4,2,-7">
<Grid Canvas.Top="2">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" ScrollViewer.CanContentScroll="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=grid, Path=RowHeaderWidth}" />
<ColumnDefinition Width="{Binding ElementName=TypeCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=NCRCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=StatusCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PStkCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=DfStkCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=QtyCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=DfCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=DfDateCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=b1, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CCodeCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=ByCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=InvAssignCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=InvCommentsCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=b2, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CStepNoCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CActionCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CAssignCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CReqCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=CComplCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=MCostCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=LabourCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=b3, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PStepCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PActionCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PAssignedCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PReqCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PCompCol, Path=ActualWidth}" />
<ColumnDefinition Width="{Binding ElementName=PDateCol, Path=ActualWidth}" />
</Grid.ColumnDefinitions>
<TextBlock Text="INVESTIGATION" Height="20" Grid.Column="10" Grid.ColumnSpan="5" Grid.Row="0"/>
<TextBlock Text="CORRECTIVE ACTION" Height="20" Grid.Column="15" Grid.ColumnSpan="8" Grid.Row="0" />
<TextBlock Text="PREVENTATIVE ACTION" Height="20" Grid.Column="23" Grid.ColumnSpan="6" Grid.Row="0"/>
</Grid>
<DataGrid x:Name="grid" Grid.Row="1" Grid.Column="0" CanUserAddRows="False" HorizontalAlignment="Center" VerticalAlignment="Top" Width="1524" Canvas.Top="44" HeadersVisibility="Column" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserResizeColumns="False" Canvas.Left="-180" CellEditEnding="grid_CurrentCellChanged" Margin="0,0,881,0">
<DataGrid.Columns>
<DataGridTextColumn x:Name="TypeCol" Binding="{Binding Type}" Header="Type" Width="50" IsReadOnly="True"/>
<DataGridTextColumn x:Name="NCRCol" Binding="{Binding NCR}" Header="NCR" Width="100" IsReadOnly="True"/>
<DataGridTextColumn x:Name="StatusCol" Binding="{Binding Status}" Header="Status" Width="50"/>
<DataGridTextColumn x:Name="PStkCol" Binding="{Binding PStkCode}" Header="Parent Stock Code" Width="120 " IsReadOnly="True"/>
<DataGridTextColumn x:Name="DfStkCol" Binding="{Binding DfStkCode}" Header="Defective Stock Code" Width="125" IsReadOnly="True"/>
<DataGridTextColumn x:Name="QtyCol" Binding="{Binding Qty}" Header="Quantity" Width="120" IsReadOnly="True"/>
<DataGridTextColumn x:Name="DfCol" Binding="{Binding Defect}" Header="Defect" Width="100" IsReadOnly="True"/>
<DataGridTextColumn x:Name="DfDateCol" Binding="{Binding Defect Date}" Header="Defect Date" Width="100" IsReadOnly="True"/>
<DataGridTemplateColumn x:Name="b1" Width="20" IsReadOnly="True"/>
<DataGridTextColumn x:Name="CCodeCol" Header ="Cause Code" Width ="80" />
<DataGridTextColumn x:Name="ByCol" Header ="By" Width ="80"/>
<DataGridTextColumn x:Name="InvAssignCol" Header ="Assigned To" Width ="100" />
<DataGridTextColumn x:Name="InvCommentsCol" Header ="Comments" Width ="100" />
<DataGridTemplateColumn x:Name="b2" Width="20" IsReadOnly="True"/>
<DataGridTextColumn x:Name="CStepNoCol" Header ="Step No" Width ="60" />
<DataGridTextColumn x:Name="CActionCol" Header ="Action" Width ="100" />
<DataGridTextColumn x:Name="CAssignCol" Header ="Assigned To" Width ="100"/>
<DataGridTextColumn x:Name="CReqCol" Header ="Reqd By" Width ="100" />
<DataGridTextColumn x:Name="CComplCol" Header ="Completed By" Width ="100"/>
<DataGridTextColumn x:Name="MCostCol" Header="Material Cost($)" Width="100"/>
<DataGridTextColumn x:Name="LabourCol" Header="Labour (Hrs)" Width="100"/>
<DataGridTemplateColumn x:Name="b3" Width="20" IsReadOnly="True"/>
<DataGridTextColumn x:Name="PStepCol" Header="Step No" Width="60"/>
<DataGridTextColumn x:Name="PActionCol" Header="Action" Width="100"/>
<DataGridTextColumn x:Name="PAssignedCol" Header="Assigned To" Width="100"/>
<DataGridTextColumn x:Name="PReqCol" Header="Reqd By" Width="100"/>
<DataGridTextColumn x:Name="PCompCol" Header="Completed By" Width="100"/>
<DataGridTextColumn x:Name="PDateCol" Header="Completed Date" Width="100"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Canvas>
Rather than trying to match the columns and ScrollBars of the DataGrid in a Grid that has no relation to it, just define the DataGrid header however you want to. You can use the HeaderTemplate property of a DataGrid.DataGridTemplateColumn... maybe something like this:
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Top Header" />
<TextBlock Grid.Row="1" Text="Bottom Header" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

Categories

Resources