ListBox TextBlock item alignment in Grid column Windows Phone - c#

I have problem with HorizontalAlignment of TextBlock in ListBox ItemTemplate. This is part of my code:
<ListBox x:Name="mealList" ItemsSource="{Binding Meals}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Margin="10" Grid.Column="0" TextWrapping="Wrap" Style="{StaticResource PhoneTextSmallStyle}"/>
<TextBlock Text="{Binding Price}" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Style="{StaticResource PhoneTextSmallStyle}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In App I have this list of things:
Actual state
But I want, that right column with "xx,- Kč" has HorizontalAlignment="Right". Every item in this column should be on the righ side of screen and below previous item. Second column in second row should be below second column in first row. Do you understand?
Can you help me? I can post more of code.

Related

Cannot align textboxes inside grid properly among themselves

I have the following DataTemplate where inside is a Grid with a 'TextBlock' and TextBox that I want to align to the center:
<DataTemplate x:Key="OneSettingsEntryTemplate" DataType="{x:Type templateHelper:InputText}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Style="{StaticResource StandardTextBlocksStyle}"
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Grid.Column="1"
Style="{StaticResource DefaultTextBoxesStyle}"
Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
In one of my UserControls I have the following code where I use the Template:
<StackPanel DataContext="{Binding ElementName=ControlForProjectSettings, Path=ViewModel}"
HorizontalAlignment="Center">
<TextBlock Style="{StaticResource HeadingTextBlocksStyle}"
Text="Project settings"/>
<ListView Background="#DAE7F5"
ItemsSource="{Binding ProjectSettingEntries}"
ItemTemplate="{StaticResource OneSettingsEntryTemplate}">
</ListView>
</StackPanel>
When I run my application and display some items, the last item has a longer text and therefore the TextBox flips to the right. Application Image
I tried playing around with the HorizontalAlignment and VerticalAlignment properties inside the Grid or also using a DockPanel instead of a Grid but couldn't find a solution. Any ideas?
Thanks to this source: WPF share column width between separate grids I solved my problem.
I added the IsSharedSizeScope to my Grid and the SharedSizeGroup property to my columns.
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>

Align controls correctly when using ItemsControl in WPF

Can someone tell me how to align and resize controls correctly when using the ItemsControl.
I want to have a description on the left and a TextBox on the right for multiple fields which are defined in an ObservableCollection to end up with something like:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
but instead I'm getting this:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
I want all the textbox to be aligned based on the largest <TextBlock>. If this was done directly in a <Grid> control, it would be straight forward as all controls are directly in the grid and you would just have the following columns definition defined
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
I thought I could use the SharedSizeGroup property in the <Grid> but it still doesn't resize correctly. Instead it only displays the <TextBlock> stretch across the <Grid>.
Here's my code:
<Grid Grid.IsSharedSizeScope="True" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Labels" />
<ColumnDefinition Width="*" SharedSizeGroup="InputControls" />
</Grid.ColumnDefinitions>
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedTemplate.Fields}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}" Grid.Column="0" Margin="5"
VerticalAlignment="Center" Background="Red" />
<TextBox Text="{Binding Path=Value}" Grid.Column="1" Margin="5"
VerticalAlignment="Center" Background="Blue" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Any idea how I can resolve this?
Thanks.
UPDATE1: I cannot get this to work as I need it to. This is what I've got so far:
<Grid Grid.Row="1" Background="Purple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="Overall" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
This ends up displaying my layout this way:
As you can see, my TextBox are correctly aligned based on the largest TextBlock but my ItemsControls is not stretched all the way across. I guess that makes sense as it is within the same grid where the ColumnDefinitions are defined.
Now, if I move the ColumnDefinitions' out this grid to the outer grid and remove all instances ofGrid.IsSharedSizeScope`, I guess the following:
Which once again is closer to what I need as my ItemsControl is now stretching all the way as I've set its Grid.ColumnSpan="2" and my TextBox are still aligned to the TextBlock and are stretching all the way across but the problem now is that the TextBlock should be smaller as the Column is set to Auto but they appear to behave as if the column was set to * and I guess I'm losing the purpose of using IsSharedSizeScope since it has been removed.
Now if I add IsSharedSizeScope="True" to the outer grid, I get the following result:
Again, this is close to what I want as my ItemsControl is stretched, my textboxes are also stretch but they are no longer aligned to the largest TextBlock.
Finally, if I add Grid.IsSharedSizeScope="True" to ItemsControl as originally suggested by #mm8,
<Grid Grid.Row="1" Background="Purple" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.ColumnSpan="2" >
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<!--<TextBlock Text="Invoice Number" Grid.Column="0" Margin="5" VerticalAlignment="Center"/>
<TextBox Text="InvoiceNumber" Grid.Column="1" Margin="5" VerticalAlignment="Center"/>-->
</Grid>
I get the following:
Which brings me back to square one, though the definitions are different?
I need to achieve the following:
What am I doing wrong??
Thanks.
Try to set the Grid.IsSharedSizeScope property of the ItemsControl itself:
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
Grid.IsSharedSizeScope="True">
Synchronizing the width of elements in an ItemsControl: https://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/
I eventually found the answer in the following article: WPF Tutorial - Grid Panel under the section: "How to share the width of a column over multiple grids".
As per article:
Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.
So my final XAML looks like this:
<Grid Grid.Row="1" Background="Purple" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<ItemsControl ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
And the outcome now finally looks correct:
Hope this helps others!

ListView.ScrollIntoView doesn't work properly

I have a ListView in a page. I select a row and then scroll ListView. the selectedItem goes out of visible area. when I call ListView.ScrollIntoView( selectedItem) it jumps to that row but the content of that row is wrong and it it filled with the last row that was visible when scrolled.
it is in xaml
<ListView
Name="LstSurahText"
SelectedValuePath="tblSuyaID"
ShowsScrollingPlaceholders="False" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<ContentControl
Content="{Binding rtb}" />
<TextBlock Text="{Binding Text}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and yhis is in code behind:
LstSurahText.ScrollIntoView(LstSurahText.SelectedItem);
anyone knows why? and How to solve it?
Update:
I just understand that contentControl make it work wrong, but I don't know why.

XAML Strech TextBlock in Grid Colum

Each list item must be
TextBlock 1 fill first row with 100% width;
TextBlock 2,3,4 must fill 33% each on separate row;
Why TextBlock 2,3,4 not strech?
<ListView.ItemTemplate><DataTemplate><StackPanel>
<TextBlock Text="{Binding Name}" />
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock TextAlignment="Right" Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding Rest}" FontSize="28"/>
<TextBlock TextAlignment="Right" Grid.Row="0" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding Currency.Name}" FontSize="25"/>
<TextBlock TextAlignment="Right" Grid.Row="0" Grid.Column="2"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding FullRest}" FontSize="22"/>
</Grid>
</StackPanel></DataTemplate></ListView.ItemTemplate>
P.S.
How i can add 1...x rows in list view in design time?
Use ListView.ItemContainerStyle
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
This code (with normal values, because I don't have the underlying data structure) works fine for me.
Different rows can have different widths however. That can be fixed by setting the Width of the StackPanel to the ActualWidth - margins of the listview.
You can find some info about how to add mock data, for usage in the designer, here: How to get mock data into listview during design time and real data at run time in WPF
I used a ListBox to bind my data in similar way.
You will need to give stackpanel specific width
And you will have to set textwrapping property to 'no wrap'
<ListBox x:Name="listbox" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="480">
<TextBlock Text="{Binding main}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock TextWrapping="NoWrap" Text="{Binding one}"/>
<TextBlock TextWrapping="NoWrap" Text="{Binding two}" Grid.Column="1"/>
<TextBlock TextWrapping="NoWrap" Text="{Binding thr}" Grid.Column="2"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This Works perfectly for me!

C# Xaml How to get listbox selected item textbox value

I'm developing windows phone 8.1 app, and I need to get value of textboxes named:"time_tb" and "task_text_tb", that are in my selected item. This is my Xaml code:
<ListBox x:Name="list" ItemsSource="{Binding tasks}" Background="White" Margin="-1,50,-1,63">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="1" Height="76" Tapped="Grid_Tapped" Width="389">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="83*" />
<ColumnDefinition Width="307*" />
</Grid.ColumnDefinitions>
<TextBox x:Name="time_tb" Margin="0,15,276,0" TextWrapping="Wrap" Text="{Binding time}" VerticalAlignment="Top" BorderBrush="#FF49B7DC" Width="83" Height="45" FontSize="18.667" Foreground="{x:Null}" Background="White" FontFamily="Segoe UI Emoji" IsReadOnly="True" TextAlignment="Center" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="task_text_tb" Margin="63,14,10,39.833" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{Binding wht}" FontSize="16" SelectionHighlightColor="#FF1455B3" Grid.RowSpan="2" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<StackPanel Height="100" Width="100"/>
</ListBox>
In your viewmodel, keep a property for the SelectedItem (binded to your list selectedItem) and 2 property for the textboxes of the current selected item that you will update when SelectedItem is changed. Then bind those 2 properties to where you want to show the values.
You may have to do some magic to find the actual selected item, because i think selected item only returns an index or something...
Hope this helps

Categories

Resources