Table in UWP App - c#

I have some UWP apps in Microsoft/Windows Store, and I want develop a new UWP app. It is a simple and static application, and I want to put a table (with always equal data - static), but I have already been searching and found nothing of how to make a table in a UWP app (XAML and C #).
Is it possible to create a table in a UWP app?

As said in the comments, you can use Telerik Grid. However, if you want to build the table yourself the Grid control will suffice.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
</Grid>
The above will create a grid with 3 rows and 3 columns. If you want to autosize the columns:
<ColumnDefinition Width="*"/>
<RowDefinition Width="Auto"/>
This will create, respectively, a column that sizes itself based on the amount of available space and a row that sizes itself to its content.
To make your grid look like a table (ie. borders between each cell), use the border control:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
...
</Grid.ColumnDefinitions>
<Border Grid.Row="2" Grid.Column="1" BorderBrush="Black" BorderThickness="2">
//Content here
</Border>
</Grid>
You can place the Border control in each 'cell' by adjusting the Grid.Row and Grid.Column properties.

The most recent version of Windows Community Toolkit features the DataGrid https://learn.microsoft.com/en-us/windows/communitytoolkit/controls/datagrid. I haven't used it myself so I don't know how easy or hard data binding it is but it looks very capable.

The Grid nad ListView are OK, but the DataGrid control will be the best choice.
Under the link you will find the MS documentation for it:
Windows Community Toolkit DataGrid XAML control documentation
It's best to use a native solution and not reinvent the wheel from scratch.
Example bellow:
<controls:DataGrid x:Name="dataGrid1"
Height="600" Margin="12"
AutoGenerateColumns="False"
ItemsSource="{x:Bind MyViewModel.Customers}">
<controls:DataGrid.Columns>
<!-- Name Column -->
<controls:DataGridTemplateColumn Header="Name">
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Padding="5,0,5,0"
Text="{x:Bind FirstName}"/>
<TextBlock Text="{x:Bind LastName}"/>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
<controls:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{x:Bind FirstName}" BorderThickness="0"/>
<TextBox Text="{x:Bind LastName}" BorderThickness="0"/>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellEditingTemplate>
</controls:DataGridTemplateColumn>
<!-- other columns below -->
</controls:DataGrid>

Related

How to structure a stacked form with WPF XAML?

On my Window, I've got a GroupBox. I'd like to build out a horizontally aligned form inside of that GroupBox. By horizontally aligned, I mean a form where the label and the input reside on the same grid row or x axis. Separate form labels + inputs reside on their own row.
Since a GroupBox can only have one child content, I assume I need to either use a Grid or StackPanel. I'm trying to use a StackPanel because that seems simpler and should achieve what I'm aiming for.
The issue I'm trying to figure out is how to group the input and label into one unit so they can reside horizontally next to each other, but stack vertically as a pair within the StackPanel.
It's probably best to use a Grid that way you an get the labels and inputs to line up vertically. While it's not impossible with a stack panel it's a whole lot harder. If you set the grid's RowDefinition heights to "Auto" the grid will only be as tall as it needs to be:
<GroupBox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Label1"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Input1}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Label2"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Input2}"/>
etc.
</Grid>
</GroupBox>
You'll probably need to play around with margins and/or padding and horizontal alignments to get the layout exactly how you want it, but this should give you the control you need to achieve what you want.
you can use a stackpanel with orientation equal to vertical inside your groupbox and inside that stackpanel you can have another stackpanel with orientation equal to horizantal for your label and input just like following sample code.
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical">
<StackPanel Name="input1" Orientation="Horizontal">
<Label Content="input1"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input2" Orientation="Horizontal">
<Label Content="input2"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input3" Orientation="Horizontal">
<Label Content="input3"/>
<TextBox/>
</StackPanel>
</StackPanel>
</GroupBox>
One feature you might find useful is grid shared size scope. It can help you align elements in multiple different Grids, by sharing their column\row sizes, like this:
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input11" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input2222222" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input3333333333333" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
</StackPanel>
</GroupBox>
I don't say that it is necessary in the code above, but that is just example. Often, you want to use grid in for example ItemTemplate of ItemsControl, and you want all items to be aligned. Here shared size scope might help.

ComboBox items in full-mode and normal-mode

I want to show an accent color chooser like what is built-in in the system.
When It's in full mode, I want it to appear as tiles with available colors, and when it appears as a drop-down list, I want it to appear as a little square and color name next to it.
The problem is that I don't know how to set two templates for full-mode and drop-down mode.
<ComboBox SelectionChanged="AccentColor_SelectionChanged">
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Yellow" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Yellow" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Blue" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Blue" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
</ComboBox>
This works only for drop down mode. How can I achieve it? (It's a Windows PHone Runtime app).
normally in wp8 when number of items in a dropdownlist becomes more than 5 items it will automatically turns to a full screen mode.else it will show in just a drop list..
In listpicker there is a property call ExpantionMode..try that or following link will help you..
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868195.aspx
try this..just edit as per your requirement.
I have just pasted my code.
<wpToolkit:ListPicker Name="cmbCountry" Background="#FFF9E2" Foreground="#333333" Grid.Column="0" ExpansionMode="FullScreenOnly" ItemsSource="{Binding Countries}" SelectionChanged="cmbCountry_SelectionChanged_1">
<wpToolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CountryName}" FontSize="20"></TextBlock>
</DataTemplate>
</wpToolkit:ListPicker.ItemTemplate>
<wpToolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<Border BorderBrush="#FFF9E2" BorderThickness="0,0,0,3">
<StackPanel Orientation="Horizontal" Width="425">
<TextBlock Text="{Binding CountryName}" FontSize="35"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</wpToolkit:ListPicker.FullModeItemTemplate>

Design Xaml grid with height = 100% and minimum row height size

Here's the problem. I have a grid with some data written in xaml:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MaxHeight="75" MinHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As you can see I'm creating a new grid for each member in my "MyObjectCollection". Ideally I think I should just create one row instead since this would make my next problem - the real problem easier.
However, I have not found any good way to do this in xaml if even possible. Is this possible without populating the collection manually from c# and setting a row-property in my objects manually in order to do something like this
<Label Name="LabelNumber" Grid.Row="{Binding ManuallyCalculatedRowID}" ... />
My primary problem is that I would like the grid/rows to all be equally high and if possible fill out the parent window. If the parent window is way too large MaxHeight should apply and I would just like some empty space below.
The parent control is a Windows Form ElementHost if that makes any difference.
Please let me know if you need any additional info.
To make all rows of equal hight we can use ItemsPanelTemplate and set it to UniformGrid that will take care of equal sizing problem:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Note that I removed row definition in ItemTemplate to lift vertical size restrictions for items. Not sure if that answers your question but that can be good starting point on the road to solution.

Button on title of ChildWindow (Silverlight) design issue

I'm designing Silverlight ChildWindow and I met one intersting problem. I defined a button on a window title as follows:
<ChildWindow.Title>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="This is textblock" Grid.Column="0"/>
<Button Content="Help" Name="btnHelp" Grid.Column="1" Width="100"
Margin="300,0,0,0" />
</Grid>
</ChildWindow.Title>
This window is resizable. When you try to resize the window, the "btnHelp" button is covered by the close button, and the "btnHelp" button is not aligned to the edge of the window also. I tried before to use a StackPanel, also I used margins in both variants (StackPanel and Grid) and they didn't help me properly. The variant in the code is latest:) Could you please give a hint, what can I do with that?
Thanks in an advance.
This is a result of what appears to be a strange choice in the ChildWindow's control template -- the Title content is not stretched, so you can't really right-align anything without hard-coding it. So, you could go ahead and just apply fixed widths to the Grid column widths:
<controls:ChildWindow.Title>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Text="This is textblock" Grid.Column="0"/>
<Button Content="Help" Name="btnHelp" Grid.Column="1" />
</Grid>
</controls:ChildWindow.Title>
That's quick-and-dirty, but not very satisfying. An alternative would be to modify the ControlTemplate (at the link above) so that it behaves how you would expect. Find the ContentControl that displays the Title, and make it stretch to fill the available space, by adding HorizontalContentAlignment="Stretch":
<Style TargetType="controls:ChildWindow" x:Key="MyChildWindowStyle">
<!-- etc ... -->
<ContentControl Content="{TemplateBinding Title}" FontWeight="Bold"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch" IsTabStop="False" Margin="6,0,6,0" VerticalAlignment="Center"/>
<!-- etc ... -->
</Style>
This allows you to use the normal layout controls like Grid, and it will render as expected:
<controls:ChildWindow Style="{StaticResource MyChildWindowStyle}"
...
<controls:ChildWindow.Title>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="This is textblock" Grid.Column="0"/>
<Button Content="Help" Name="btnHelp" Grid.Column="1" Width="100"/>
</Grid>
</controls:ChildWindow.Title>

Trouble with Grid and StackPanel - Bindings

OK, I'm having issues properly using a ScrollViewer (containing an ItemsControl) inside a StackPanel.
The thing is the scrolling works, however :
No matter how much the user scrolls down, the bottom lines of the tables are not visible
When scrolling is... "released", the table pops back up...
<ScrollViewer Height="Auto">
<ItemsControl ItemsSource="{Binding Items, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Top" Margin="0,0,0,0" x:Name="ResTable">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.10*"/>
<ColumnDefinition Width="0.30*" />
<ColumnDefinition Width="0.30*"/>
<ColumnDefinition Width="0.30*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="{Binding [num]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="1" Text="{Binding [A]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="2" Text="{Binding [B]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="3" Text="{Binding [C]}" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Any ideas?
P.S.
I've had a look at some of the other answers to similar issues, but none seems to be working...
My main idea is to display a table, with a fixed header, and scrollable contents (populated via Bindings) - ok, and there are also a couple of things on the top of the page (apart from the table I mean)
I guess the issue is that you should probably use parent element like Grid, not StackPanel, because StackPanel has its drawbacks when resizing child items with scrolls and so on.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Put headers in Grid.Row="0" -->
<!-- Put Scrollviewer in Grid.Row="1" -->
</Grid>
Also Height="Auto" attribute can be removed from ScrollViewer, you might want to use VerticalAlignment="Stretch" for item to take all the available space. I hope this is what you are trying to achieve.

Categories