Multiple Header Columns datagrid wpf - wpf

I am working on attendance report. Here I am getting Headers Startdate to enddate between dates. my problem to create sub-columns under the headers. Below is the screenshot which I want to get data structure.
enter image description here
I want AM and PM under the startdate to enddate below is the code to get header dates.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim startDate As Date = CType(dtpStartDate.SelectedDate, DateTime)
Dim endDate As Date = CType(dtpEndDate.SelectedDate, DateTime)
While startDate <= endDate
Dim newColumn As DataGridTextColumn = New DataGridTextColumn()
newColumn.Header = startDate.ToShortDateString()
dgTemplate.Columns.Add(newColumn)
startDate = startDate.AddDays(1)
End While
End Sub
please help me to get sub-columns as AM and PM along with dates.
Below XAML
<DataGrid x:Name="dgTemplate" Margin="261,0,0,0" >
<DatePicker x:Name="Startdate" HorizontalAlignment="Left" Margin="42,133,0,0" VerticalAlignment="Top"/>
<DatePicker x:Name="Enddate" HorizontalAlignment="Left" Margin="40,0,0,0" VerticalAlignment="Center"/>
<Button x:Name="Button" Click="Button_Click" Content="Button" HorizontalAlignment="Left" Margin="35,325,0,0" VerticalAlignment="Top"/>
<Window x:Class="test106.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:test106"
mc:Ignorable="d"
xmlns:mynamespace="clr-namespace:test106"
Title="MainWindow" Height="450" Width="800">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:DataGridRowItem}">
<DataGrid ItemsSource="{Binding Columns[0].TableData}"
local:DataGridHelper.IsSynchronizeSelectedRowEnabled="True"
local:DataGridHelper.SynchronizeGroupKey="A"
RowHeaderWidth="0"
BorderThickness="0" />

Related

In WPF app the filepath is not showing from right end in textbox

I have a textbox in WPF window to show the path of file and browse button beside the textbox, I am selecting a file from (tfs) browser and I want to show the full path aligned from right side but it is showing from left side only.
The Image show the path showed from left
I tried HorizontalAlignment,VerticalAlignment,HorizontalContentAlignment but nothing is helping.
I want to display it from right end.
I have referred
Show right end of text line in TextBox
TextBox.TextAlign right-side alignment has no effect in certain conditions?
Can anyone Help?
Here is the code
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label x:Name="label" Content="Source :
" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="1.144,1.871" Margin="10,27,0,0"/>
<TextBox x:Name="txtSourceFile" HorizontalAlignment="Left" Height="23" Margin="67,34,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="400" TextAlignment="Justify" HorizontalContentAlignment="Right" />
<Button x:Name="btnBrowseSource" Content="Browse" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="379,62,0,0" Click="btnBrowseSource_Click" />
</Grid>
</Window>
OK, so its not that trivial as setting a property on text box what you can do is declare this method:
private void ScrollToEnd()
{
var sv = (ScrollViewer)txtSourceFile.Template.FindName("PART_ContentHost", txtSourceFile);
sv.ScrollToHorizontalOffset(sv.ExtentWidth);
}
And call it whenever your textbox value is changed.
I had the same problem and added a method for the Loaded and TextChanged event
<TextBox Loaded="FolderTB_ScrolltoEnd" TextChanged="FolderTB_ScrolltoEnd" ... />
and for setting the offset
private void FolderTB_ScrolltoEnd(object sender, EventArgs e)
{
((TextBox)sender).ScrollToHorizontalOffset(((TextBox)sender).ExtentWidth);
}

Issue binding datatable to WPF datagrid

My XAML is as follows:
<DataGrid x:Name="WaterfallDataGrid" HorizontalAlignment="Left" Height="540" Margin="10,410,0,0" VerticalAlignment="Top" Width="1650" CanUserSortColumns="False" ColumnWidth="60">
<DataGrid.Columns>
<DataGridTextColumn Header="Load" Binding="{Binding Load}"></DataGridTextColumn>
<DataGridTextColumn Header="PF" Binding="{Binding PF}"></DataGridTextColumn>
<DataGridTextColumn Header="Spare" Binding="{Binding Spare}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
My VB.net code is as follows:
Dim dt3 As New DataTable("Waterfall")
dt3.Columns.Add("Load")
dt3.Columns.Add("PF")
dt3.Columns.Add("Spare")
dt3.rows.add(New Objecet() {"full load", "0.8", "20%"})
WaterfallDataGrid.itemSource = dt3.defaultview
While the datatable does get displayed on the datagrid, it creates another 3 new columns (Load, PF and Spar) in addition to the original 3 columns I created in XAML.
How do I bind the VB.net code to the XAML datagrid?
Here is the screenshot following Ed's code
Here is the code that I modify following Mark's comment.
<Window x:Class="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:Datagrid_Binding"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="WaterfallDataGrid" HorizontalAlignment="Left" Height="170" Margin="85,65,0,0" VerticalAlignment="Top" Width="340" AutoGenerateColumns="False"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Height="25" Margin="380,255,0,0" VerticalAlignment="Top" Width="45"/>
</Grid>
</Window>
And this is the VB code
Class MainWindow
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
Dim dt3 As New DataTable("Waterfall")
dt3.Columns.Add("Load")
dt3.Columns.Add("PF")
dt3.Columns.Add("Spare")
'dt3.rows.add(New Object() {"full load", "0.8", "20%"})
dt3.Rows.Add("full load", "0.8", "20%")
WaterfallDataGrid.ItemsSource = dt3.DefaultView
End Sub
End Class
The datagrid does not show any data at all. It shows a collapsed row somehow. Screenshot as follows:
I think the issue is that if I don't pre-defined the columns in XAML and I defined the rows in vb.net but yet the autogeneratecolumn is set to false, there is no way for VB to programmatically create the columns during runtime so what I am seeing here is a collapsed row.
I think the approach would be to pre-defined the columns in XAML and then bind the data to the XAML columns but none of the codes work....really frustrating.
I think that perhaps the screenshot in the question doesn't relate to the code shown. If the only issue with your initial code was the extra columns being generated, you just need to add AutoGenerateColumns="False" to the DataGrid XAML:
<DataGrid x:Name="WaterfallDataGrid"
HorizontalAlignment="Left"
Height="540"
Margin="10,410,0,0"
VerticalAlignment="Top"
Width="1650"
CanUserSortColumns="False"
ColumnWidth="60"
AutoGenerateColumns="False">
Also, since DataRowCollection.Add takes a ParamArray argument, you don't need to create the Object array and can just pass in the column values individually, which is a bit easier to read, e.g.
dt3.Rows.Add("full load", "0.8", "20%")
When you set the AutoGenerateColumns property of the DataGrid to False you need to explitly define the columns yourself so use your original XAML markup with the addition of AutoGenerateColumns="False" and you should see the three columns:
<DataGrid x:Name="WaterfallDataGrid" HorizontalAlignment="Left" Height="540" Margin="10,410,0,0" VerticalAlignment="Top" Width="1650" CanUserSortColumns="False" ColumnWidth="60"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Load" Binding="{Binding Load}"></DataGridTextColumn>
<DataGridTextColumn Header="PF" Binding="{Binding PF}"></DataGridTextColumn>
<DataGridTextColumn Header="Spare" Binding="{Binding Spare}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
To get rid of the extra blank row that is there for the user to be able to add a new row, you could set the CanUserAddRows property to False:
<DataGrid x:Name="WaterfallDataGrid" CanUserAddRows="False" ...
Yes I am aware of that. The problem is that whilst I can create 3 columns in XAML, I am unable to bind the data to the column via my VB code above.
The following complete code sample does work as expected for me.
MainWindow.xaml.vb:
Class MainWindow
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim dt3 As New DataTable("Waterfall")
dt3.Columns.Add("Load")
dt3.Columns.Add("PF")
dt3.Columns.Add("Spare")
'dt3.rows.add(New Object() {"full load", "0.8", "20%"})
dt3.Rows.Add("full load", "0.8", "20%")
WaterfallDataGrid.ItemsSource = dt3.DefaultView
End Sub
End Class
MainWindow.xaml:
<Window
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:WpfApplicationVb1"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="WaterfallDataGrid" CanUserSortColumns="False" ColumnWidth="60" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Load" Binding="{Binding Load}"></DataGridTextColumn>
<DataGridTextColumn Header="PF" Binding="{Binding PF}"></DataGridTextColumn>
<DataGridTextColumn Header="Spare" Binding="{Binding Spare}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

Page can have only Window or Frame as parent

I just want to switch between WPF pages, but getting above mentioned error:Page can have only Window or Frame as parent.
here is my code
Imports System.Windows.Forms
Public Class Page1
Private Sub btn1_Click(sender As Object, e As RoutedEventArgs) Handles btn1.Click
Try
Dim dd As New Page2
Me.Content = dd
Me.txt1.Text = (dd.txt10.Text)
Catch ex As Exception
txt1.Text = ex.Message
End Try
xaml file code
<Page x:Class="Page2"
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"
Title="Page2">
<Grid>
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="163,62,0,0" VerticalAlignment="Top" Width="101" Height="55"/>
<TextBox x:Name="txt10" HorizontalAlignment="Left" Height="23" Margin="38,81,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
</Grid>
please guide me what i am doing wrong?
Based on the name Page1 I assume it is a Page. Put a Frame in Page1 and load Page2 into the Frame.

How to bind dataset to datagrid in XAML?

I am binding a dataset to datagrid in XAML using Object dataprovider.
Here is my code:
<UserControl xmlns:my="clr-namespace:Pauspan_n_"
x:Class="UCitems"
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="700" d:DesignWidth="1100">
<UserControl.Resources>
<ObjectDataProvider x:Key="sizes" ObjectType="{x:Type my:Item_sizes}">
</ObjectDataProvider>
<ObjectDataProvider x:Key="sizes2" ObjectInstance="{StaticResource sizes}" MethodName="Getsizes">
</ObjectDataProvider>
</UserControl.Resources>
<Grid Height="700" Width="1100">
<DataGrid AutoGenerateColumns="False" Height="154" HorizontalAlignment="Left" Margin="819,55,0,0"
Name="dgv_itemsizes" VerticalAlignment="Top" Width="242"
ItemsSource="{Binding Source={StaticResource sizes2}}" ></DataGrid>
</Grid>
</UserControl>
My dataset name is Item_sizes and the datatable name is sizes,
but datagrid shows nothing in it.
I think I may want something like this:
Public Overridable Overloads Function GetSizes() As Item_sizes.sizesDataTable
Me.Adapter.SelectCommand = Me.CommandCollection(0)
Dim dataTable As Item_sizes.sizesDataTable = New Item_sizes.sizesDataTable()
Me.Adapter.Fill(dataTable)
Return dataTable
End Function

Object Reference not set error while trying to set the visiblity of grid

I was trying to set the visiblity of a Grid from code behind.
grdStopTimeOut.Visibility = Windows.Visibility.Visible
I have declared this grid in XAML and have set the visiblity to Visible.
<Grid Name="grdTimeTStopCondition" Visibility="Hidden" Margin="0,29,0,-6">
Somehow when the application runs the grid is coming as nothing and the exceptions is thrown.
Anybody have any idea why it is happening??
XAML File
<Page x:Class="Page1"
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"
Title="Page1">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Name="cmbStopConditions" VerticalAlignment="Top" Width="86" SelectedIndex="0">
<ComboBoxItem Content="Expression"></ComboBoxItem>
<ComboBoxItem Content="Manual"></ComboBoxItem>
</ComboBox>
<Grid Name="grdStopTimeOut" Visibility="Visible" >
<Label Content="Timeout" Height="28" HorizontalAlignment="Left" Name="lblTimeout_stopcond" VerticalAlignment="Top" Margin="0,29,0,0" />
<TextBox Height="23" HorizontalAlignment="Left" Name="txtStopTimeout" VerticalAlignment="Top" Width="30" Margin="60,29,0,0" />
<Label Content="secs" Height="28" HorizontalAlignment="Left" Name="lblTimeoutSec_stopCond" VerticalAlignment="Top" Width="39" Margin="105,24,0,0" />
</Grid>
</Grid>
</Page>
CodeBehind
Class Page1
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Private Sub cmbStopConditions_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cmbStopConditions.SelectionChanged
Dim item As ComboBoxItem = TryCast(cmbStopConditions.SelectedItem, ComboBoxItem)
If item IsNot Nothing Then
If Convert.ToString(item.Content) = "Expression" Then
grdStopTimeOut.Visibility = Windows.Visibility.Visible
ElseIf Convert.ToString(item.Content) = "Manual" Then
grdStopTimeOut.Visibility = Windows.Visibility.Hidden
End If
End If
End Sub
End Class
regards,
SKB
Edit: The handler can occur before the grid is initialized, so a null-check is in order.
Are you calling this before InitializeComponent? That for one would explain the lack of a reference because all the fields are hooked up with the named controls in that method.

Resources