I have a ListView in the first row of a Grid. There is some data which fills each row by double clicking on items in the GridControl below. So the main idea of it is to click on a GridControl item so it may be seen in the ListView too.
The problem is very strange: the first item is always being added and looks normally in the ListView, but then the next items can get very large, in random order.
I haven't found any ListView.Rows property or similar. So I cannot explicitly set it how I want.
There is a Grid, in which ListView is keeping:
<Grid.RowDefinitions>
<RowDefinition Height="200" x:Name="xSelectedRow"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
There is ListView with some columns:
<ListView x:Name="xListSelected" BorderBrush="Transparent" Grid.Row="0"
ItemsSource="{Binding SelectedItemsSource}"
SelectedItem="{Binding SelectedSelectedItem}">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Padding" Value="10 2 4 2" />
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction
Command="{Binding RemoveSelectedItemCommand}"
CommandParameter="{Binding ElementName=LayoutRoot, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Width="{Binding Path=ActualWidth, ElementName=xProjectViewId}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding Id}"
FontSize="14"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="{Binding Path=ActualWidth, ElementName=xName}" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding Name}"
FontSize="14"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Here is a link to an image: https://imgbbb.com/image/jkdJp
There is example in the image, where the 1st, 2nd, and 3rd rows are looking normally, but the fourth is very large. And it seems not always be like this: the next two rows can be normal, but then the next three are large again.
Have you ever seen such problem?
The answer to your question about why some rows are higher is:
You set the textblocks to wrap and the strings in them then make those controls grow.
It's not random.
Decide which you prefer.
The current increased height of some rows.
Truncating the strings by setting maxheight.
Lowering the size of (presumably) the Name variable so they can only enter so much.
Some mix.
Re-arranging your UI in some other way.
Assuming that the grid you are talking about is written here:
<Grid.RowDefinitions>
<RowDefinition Height="200" x:Name="xSelectedRow"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
Your height definitions for each row is inconsistent.
A specific number will give it the specific height, but some parameters might change and scale this. So this would explain why your first row remains correct.
A star (*) will tell the code to make the row proportional to the grid
"Auto" make the row to adapt to the size of the content. Wraping and padding can make this give unexpected results.
I suggest to try to either give all of the rows a large enough specific height (200) or setting all of them to Star (*)
Related
i have a listbox with a lot of items, and each items when clicked go to a new page, what i want is when i return from the second page, stay at the same position of the item is clicked!
Thats my list!
<ListBox x:Name="list" Loaded="ListView_Loaded" SelectedItem="true" SelectionChanged="searchResultsList_SelectionChanged" ItemsSource="{Binding}" Background="{x:Null}">
<!--<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,0,0,15" />
</Style>
</ListView.ItemContainerStyle>-->
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Width="80" Height="80">
<Image Source="{Binding Caminho}" />
</Border>
<StackPanel Margin="0,16,0,0" Grid.Column="2">
<TextBlock Foreground="White" Text="{Binding NomeCurso}" TextWrapping="Wrap" FontSize="{StaticResource TextStyleExtraLargeFontSize}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
thanks!
If you are using WinRT you can write the following code in your page constructor to cache it, this way the positions will be intact after you go back to this page:
this.NavigationCacheMode = NavigationCacheMode.Required;
And from your sample I cant really see if you are using ListBox or ListView, I will presume ListView which is better as the ListBox is somewhat not needed anymore.
One thing I also noticed is that you use a simple {Binding} for your ItemsSource so maybe it is reset every time you go back because of this (if you are doing something that does this, as this is not visible from your sample code). I always have an additional property of type ObservableCollection and bind to it for example ItemsSource={Binding MyItems}. This way the list is reset only when I reset the property MyItems.
I have a grid, with 3 rows.
Row 2 has a variable height, the window is resizable, and I have a datagrid on Row 3, held within a scrollviewer, within a tabcontrol.
When there are many items in the scrollviewer, the scrollviewer expands until it reaches the "max height" available to it, however that max height is infinity... so it keeps growing and growing. What I want it to do, is stop expanding if that would mean it is pushing the parent grid out of bounds, and instead use its scroll functionality... Here is the general layout of it:
<TabControl Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3">
<TabItem Header="Weapons">
<ScrollViewer>
<DataGrid>
...
</DataGrid>
</ScrollViewer>
</TabItem>
</TabControl>
That is held within a grid which has 3 rows and 3 columns. There is content in rows 0 and 1 which I didnt put here, and obviously I took out the unnecessary info from Datagrid etc...
Example of what I see:
As requested, the whole XAML. Not exactly short, which is why I thought the simplified version above would be better. XAML - Too large to fit in post
OK, so its there. I am looking at both datagrids held in different tabs of the tabcontrol on Row 2 of the grid.
Condensed "full" xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="1">
<Image Source="{StaticResource EmptySlot}" Margin="0" Width="34"/>
<Image Source="{Binding AuraSlot, FallbackValue={StaticResource AuraSlot}}" Margin="0" Width="34"/>
</Grid>
<Popup AllowsTransparency="True" Placement="Relative" PlacementTarget="{Binding ElementName=MainWindowName}" IsOpen="{Binding WeaponTooltipOpen}" HorizontalOffset="{Binding WeaponOffsetX}" VerticalOffset="{Binding WeaponOffsetY}" PopupAnimation="Fade" OpacityMask="White" >
...
</Popup>
<Grid Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3">
<Expander orizontalAlignment="Center">
<Expander.Header>
<TextBlock Text="Equipment Slots" HorizontalAlignment="Center" />
</Expander.Header>
<Grid Grid.Row="0" Grid.Column="1">
...
</Grid>
</Expander>
</Grid>
<TabControl Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3">
<TabItem Header="Weapons">
<Grid>
<ScrollViewer CanContentScroll="True" >
<DataGrid Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" ItemsSource="{Binding GroupedWeapons}" AutoGenerateColumns="False" IsReadOnly="True" AlternatingRowBackground="Gainsboro" AlternationCount="2" RowHeaderWidth="0">
<DataGrid.GroupStyle>
<GroupStyle>
...
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
...
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
...
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</ScrollViewer>
</Grid>
</TabItem>
</TabControl>
</Grid>
OK, eventually found the problem.
I don't really knwo the reason as to WHY this was the problem, because it doesn't really make sense to me, but WAY up in the code I had things wrapped in a stackpanel. The only 2 things stacked there were a textblock, and a Grid, with the grid containing a ton of other things, including all the code posted along with the question. Taking out that stackpanel made it work correctly, so I have now permanently replaced the stackpanel with another grid, using 2 differnet rows. :)
I have been trying to get dynamic column width to work for my simple WP8.1 app. The goal is to have the first column take up half of the listbox, and the other two columns a quarter each. I hoped to do this by assigning a dynamic width, using the * indicator as described here.
This let me to the piece of xaml code at the bottom of my post.
In my MainPage I set the DataContext to an ObservableCollection, and all the data shows up in their respective columns, the columns just do not get the desired width (they are all as small as can be).
What prevents my dynamic width from working? I have toyed around with HorizontalAlignment and Width of TextBoxes too, but with no success. I tried to look around for answers, and I even used some examples that did work, but that did not bring me closer to understanding why it does not work here.
Thanks in advance.
<Grid>
<ListBox Name="transactionListBox" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Category}"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Amount}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
The item Grid itself is being sized-to-fit by the ListBox. You can override this behavior by setting the ItemContainerStyle to make the ListBoxItems stretch to fill horizontally:
<ListBox Name="transactionListBox" ItemsSource="{Binding}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
...
</ListBox>
I think you need a constraining width on the ListBox or Grid. With your code, the grid and ListBox will re-size to fit the content, so there is no need for the dynamic column definitions.
I have run into a bizarre problem. I am displaying a UserControl within a UserControl and at the moment each contains a completely identical ListView, as in I copied and pasted it from one to the other. On the parent UserControl, the ListView displays properly, but on the sub-UserControl (whatever it's called), the ListView columns refuse to stretch to fit their content. I have no idea why this is happening since the code of both ListViews is exactly the same. Both are placed directly on the grid.
On the top left is the ListView from the parent control and on the bottom right is that of the child control. Here is the code for both ListViews:
<ListView ItemsSource="{Binding Adventurers}"
Name="AdvListView"
HorizontalAlignment="Stretch"
Grid.Column="2"
Grid.ColumnSpan="1"
Grid.Row="2"
ScrollViewer.CanContentScroll="False"
BorderThickness="3">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding ShowAdvWindowCommand}"
CommandParameter="{Binding ElementName=AdvListView, Path=SelectedItem}"
PassEventArgsToCommand="False" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="NameTemplate">
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Name}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" />
</DataTemplate>
<DataTemplate x:Key="StatusTemplate">
<TextBlock Margin="2,1,1,1" Text="{Binding Status}" VerticalAlignment="Center" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" />
<GridViewColumn Header="Status" CellTemplate="{StaticResource StatusTemplate}" />
</GridView>
</ListView.View>
</ListView>
Why would this work on one and not the other? I'm really at a loss at this point.
Update: In the parent UserControl, the grid layout is:
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
//Listview here among other controls
</Grid>
In the child:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
//Listview here
</Grid>
Modifying Grid.Row, Grid.Column, RowSpan, or ColumnSpan to be correct doesn't fix the problem.
Update: A bit more info that may be relevant: When I try to use Snoop on my program. I get this error:
"BindingFailure was detected - The assembly with display name 'Snoop.XmlSerializers' failed to load in the 'LoadFrom' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileNotFoundException: Could not load file or assembly 'Snoop.XmlSerializers, Version=2.8.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
Snoop has no problem with other programs. I don't know if this is related to the issue at all, but I figured I'd post it anyways.
Update: I don't think this would matter, but just to be thorough, here is where the child UserControl is created within the parent:
<Grid>
//Other controls
<UserControl Grid.Column="3"
Grid.Row="3"
Visibility="{Binding AdventurerInfoVisibility}">
<view:AdventurerInfoView />
</UserControl>
</Grid>
At this point I'm completely stumped. I can create a copy of the ListView in the parent UserControl and have it display properly... but for some reason it doesn't want to behave in the child UserControl... I'm open to any ideas and if you need more code I would be more than happy to provide it.
After much tinkering and frustration, I found out what was causing the problem. The child UserControl's Visibility was set to Collapsed by default and was made visible by a button click. When I made it visible by default, the columns stretched properly.
Now I just need to find out how to allow it to start collapsed and still maintain the stretched column width.
I create a deom use your code, and it does not to repeat your problem.
I think maybe your child usercontrol had some TextBlock style, and override your container setting.
Inside my XAML/C# app for Windows 8 Store, I am trying to create a ListView where each ListItem is a horizontal Grid, so I am using the XAML below:
<ListView Name="ResultsView">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding BestRank}" Grid.Column="0"/>
<TextBlock Text="{Binding PlayerName}" Grid.Column="1"/>
<TextBlock Text="{Binding BestScore}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When I run this program, the listview contains all the items from the list it is bound to (through code behind). However in every list-item, contents of all three columns appear together without any space between them. When I create a similar grid outside the listview, it displays fine and takes up entire width of the screen and divides it between the three columns as specified in the XAML above.
What am I doing wrong?
I believe the issue is the ItemContainerStyle needs to have a HorizontalContentAlignment of Stretch. Try this adding this to the ListView:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
Both the ListBox and the Grid should have HorizontalContentAlignment="Stretch"
Specify the width of the grid or add the style as a resource to the grid. Add this right after your </Grid.ColumnDefinitions> line.
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="Margin" Value="4" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>
This will set the properties to all of the TextBlocks in the Grid. You might only need the Margin property. Also consider the properties Width and Padding. You can override this default by setting the property on any given TextBlock to something that isn't the default from the Style.
The default ItemsPanelTemplate is a stack panel as far as I recall meaning that it won't automatically give it's children stretch behavior. You will need to change it, I will edit in a sec just on my mobile waiting for my laptop to boot up :)
Edit:
Er no ignore that I was thinking of ItemsControl, JBrooks is right, just make sure HorizontalContentAlignment is set to Stretch as the default is Left.
<ListView Name="ResultsView" HorizontalContentAlignment="Stretch">
That should work fine - any controls that use XXXXContentAlignment seem to default to Left which I think its a bit inconsistent vs other controls (such as Grid)
actually this is not a problem of Listview. Problem is where you are putting it in? Put your list view in grid. It should work
<ListView Name="ResultsView"
HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding BestRank}" Grid.Column="0"/>
<TextBlock Text="{Binding PlayerName}" Grid.Column="1"/>
<TextBlock Text="{Binding BestScore}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>