Windows 8 GridView groups width - c#

I have problem with my gridview. I'm displaying grouped data in it and using VariableSizedWrapGrid for displaying items. The problem is that every group has the same width equal to the most item. Even if a group contains only 1 item it has width like it was 20 items there. How to make these ItemsPanels have variable width?
My issue is almost the same as described here but when I use VirtualizingStackPanel as GridView.ItemsPanel my VariableSizedWrapGrid is displayed in one row and I need it to be displayed in two rows.
<SemanticZoom.ZoomedInView>
<GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False"
ScrollViewer.IsVerticalScrollChainingEnabled="False"
ItemTemplate="{StaticResource PatientMediaFileBigItemTemplate}"
ItemsSource="{Binding Source={StaticResource PatientVisits} }"
IsItemClickEnabled="True"
SelectionMode="None"
Margin="0,0,0,0" ItemClick="MediaFileIcon_Click"
>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Button Content="{Binding DateOfVisit, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:dd MMM yyyy}'}" FontSize="28" Foreground="Black" BorderThickness="0" Click="ButtonVisit_OnClick"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0" Width="Auto" Background="BlueViolet"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
</SemanticZoom.ZoomedInView>

You might need to change the ItemsPanel of your GridView to a StackPanel, but note this will limit the number of items you can put in your GridView as it disables virtualization. A better option might be to keep showing a limited number of items in a group, but add a button (really the group header button with a chevron glyph should work) to navigate to a full view of the selected group.

Related

WPF Excel-like Arrow key feature with Textboxes

I have about 600 text boxes side-by-side (looks like a matrix). Each of the text box is named by row and column number. i.e.
textbox_12_25 would be textbox in 12th row and 25th column.
Is there way to implement features like Excel using Arrowkeys and Enter?
I am pretty new to C# and WPF, so a detailed and simple answers would be appreciated.
Use a list box and modify the ItemTemplate and ItemsPanel
<ListBox ItemsSource="{Binding ShippingBays}" FontSize="14" Grid.Row="2" SelectedItem="{Binding SelectedBay}" Background="White" FocusVisualStyle="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding Description}" FontWeight="SemiBold" FontFamily="Arial" FontSize="12" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding ColumnCount}" Rows="{Binding RowCount}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
This is some of the code I wrote for a similar application. Though I do not enter information in the boxes, I just display it. I know this isn't an exact answer but its a way to do it even if you had to modify how you are adding the boxes, etc.
My grid appears with A at the bottom because i'm sorting by RowCount descending, otherwise A would be the top row, just like excel.

ListView vs ListBox performance

So I have been dealing with a problem representing 10k+ rows in a listview (I might need pagination, but this is not about that), I had 2 problems:
Item source loading took at least 10 seconds to load into the listview which made my UI hang
Lag while focusing the listview
So I wanted to compare the same thing using a listbox than a datagrid. And I was amazed how the listbox reduced the loading time to almost nothing and also there is no lag.
Listview:
<ListView ItemsSource="{Binding SymbolContext}" BorderThickness="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ListBox:
<ListBox ItemsSource="{Binding SymbolContext}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So my question is why did it take for the listview so much to represent the data and why did the listbox perform so well?

WPF/MVVM Wrap panel orientation

I'd like to display basically a matrix of buttons, the number of buttons change in runtime.
My problem is that I want them to be next to each other to fill up all the space I give them. I thought WrapPanel is the perfect way to do that but it puts the buttons under each other and I have no idea how to solve it.
<Grid>
<WrapPanel Width="250" Height="50" Orientation="Horizontal" Margin="543,442,73,162" >
<ItemsControl ItemsSource="{Binding States}" >
<ItemsControl.ItemTemplate>
<DataTemplate >
<Button Width="50" Height="25" Content="{Binding StateName}" Padding="0" ></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</WrapPanel>...</Grid>
States is a list of Items that contains a name and a ID number. If i want to add or remove buttons I modify the list. So the buttons appear but in vertical order and they go beyond the limits of the WrapPanel so if it is not big enough only some appears. They only use 50 width from the 250 and more then the 50 height. In this case if I put 5 buttons in it only shows 2 of them.
Don't wrap ItemsControl inside WrapPanel. Instead set it as ItemsPanel of ItemsControl.
<ItemsControl ItemsSource="{Binding States}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="50" Height="25" Content="{Binding StateName}"
Padding="0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

Scroll ListBox in terms of logical units with horizontal orientation

In my application, I have the following ListBox:
<ListBox ItemsSource="{Binding Path=ItemsSource}" ScrollViewer.CanContentScroll="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Height="300">
<!-- One ProgressBar and multiple TextBlocks -->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This way, I have multiple items on the same line. If there are too many items for one line, the following items are sent to the next line.
The problem I am having is that ScrollViewer.CanContentScroll="True" has no effect on the ListBox. The scroll down is still processing in terms of physical units. When I comment the ListBox.ItemsPanel part of the XAML, the scroll down is working properly, but only one item is displayed on each line...
So my question is the following: How to combine the scroll down in terms of logical units with a horizontal orientation of the items?
Thanks!

Change GridView header placement

I have a normal GridView, that displays grouped data. My goal is to move the header (a button) from the top of the group to the left of the group.
<GridView>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid>
<Button Content="{Binding Title}"/>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemWidth="240" ItemHeight="160" Orientation="Vertical" Margin="0,0,80,0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
<GridView.ItemTemplate>
<!-- item template -->
</GridView.ItemTemplate>
</GridView>
An answer to this question Grouping GridView in Windows 8 Metro App - while not completely the same desired layout - says that the desired layout is not possible without adding an extra "dummy tile".
I'm wondering if it is possible to achieve my goal - to move the header from the top of the group to the left of the group - without such an extra "dummy tile".
You need to edit the header container style. In Visual Studio, right-click the GridView and select
Edit Group Style -> Edit Generated Item Container (Container Style) -> Edit a Copy
You will see the Group Header, which is a Content Control, and the Group Items, which are an ItemsControl. Both are contained inside a grid that, in the default, is simple two rows. You can add a column, move the Group Header into Grid.Column=0 & Grid.Row=1 and you should be good to go.

Categories