I am trying to display the listview group items as like in the attached screenshot, but still i have facing issue while displaying group view items
Requirement:
Group header needs to display in horizontal alignment and corresponding group items are needs to be aligned in vertical alignment
<ListView
x:Name="listview"
BorderThickness="0"
ItemsSource="{Binding Source={StaticResource cvs}}"
SelectedItem="{Binding SelectedProduct}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Product}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Padding="5,0,0,0"
FontSize="14"
FontWeight="Bold"
Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<StackPanel Orientation="Vertical">
<ContentPresenter/>
<ItemsPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
Please suggestion a solution to achieve this.
To change the orientation you would have to set the GroupStyle.Panel. Because of your requirement to arrange the items multiline you should use a WrapPanel.
To make it behave properly you should disable the horizontal ScrollViewer of the ListView (to allow the items to wrap) and give the ListView a fixed height (in order to make the vertical ScrollViewer visible).
Since you don't modify the layout of the GroupItem and the ListView you can safely remove the GroupStyle.ContainerStyle (at least the Controltemplate override) and the ListView.ItemsPanel template override. In fact setting ItemsPanelTemplate of a ListBox or ListView explicitly to StackPanel or generally to something other than a VirtualizingPanel removes the ability to virtualize items. UI virtualization significantly improves performance, so you don't want to disable it.
<ListView ItemsSource="{Binding Source={StaticResource cvs}}"
Height="400"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Padding="5,0,0,0"
FontSize="14"
FontWeight="Bold"
Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
You should define the Panel property for GroupStyle and you can remove the ItemsPanel for the ListView:
<GroupStyle.Panel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
Complete code for setting the groups for anyone interested:
<Window.Resources>
<CollectionViewSource x:Key='cvs'
Source="{Binding Path=Products}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ProductType" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<ListView
x:Name="listview"
BorderThickness="0"
ItemsSource="{Binding Source={StaticResource cvs}}"
SelectedItem="{Binding SelectedProduct}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Product}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Padding="5,0,0,0"
FontSize="14"
FontWeight="Bold"
Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<StackPanel Orientation="Vertical">
<ContentPresenter/>
<ItemsPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
Regarding the model used: I set up a simple ProductCvs class
public class ProductCvs
{
public string Product { get; set; }
public string ProductType { get; set; }
}
Related
I have a list item with Key and Value pair. I have binding the Key in list box its display the correct output. But Value is not showing. I know this is very basic question. I am New for WPF. I have referred many sites and answers But I don't know where I have done mistake on my code. Please anybody help me to achieve this. My sample code is mentioned below,
MainWindow.xaml
<ListBox
Name="memberCollection"
Grid.Row="0"
MinWidth="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0"
ItemsSource="{Binding MainValues}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
MainViewModel
public MainViewModel(TestCollection testCollection)
{
MainValues = new ObservableCollection<Details>();
TestCollections = testCollection;
foreach (var _val in TestCollection.GroupingMainCollection)
{
MainValues.Add(new Details() { Key = _val.Key, Values = _val.Value});
}
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(MainValues);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Key");
view.GroupDescriptions.Add(groupDescription);
}
DetailsModel
public class Details
{
public string Key { get; set; }
public ObservableCollection<IValue> Values { get; set; }
}
IValue
public interface IValue
{
string Name { get; set; }
string ID { get; set; }
}
You don't want to display Values collection in group header but under group content, so move ItemsControl from under Expander header and set it as ItemTemplate.
Here is working code:
<ListBox
Name="memberCollection"
Grid.Row="0"
MinWidth="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0"
ItemsSource="{Binding MainValues}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Edit:
If I understand you correctly, you want to display collection of items and then choose only single item within collection of collection of items!
Checkout code below which uses ItemsControl instead of using ListView/ListBox:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding MainValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1" Padding="5" Margin="5">
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Key}" FontWeight="Bold" />
</StackPanel>
</Expander.Header>
<ListBox ItemsSource="{Binding Values}"
BorderThickness="0,1,0,0" Margin="0,5,0,0"
DisplayMemberPath="Name" SelectedValuePath="Id" />
</Expander>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
I wan't to display a grid view list item but I don't know why the gridview (in purple) take all the place I wan't but the grid elements does not take all the width evailable they wrap the content, what I'm missing ?
<GridView
Background="Purple"
Grid.Row="1"
Margin="20,20,20,0"
ItemsSource="{Binding MyItems}"
Style="{StaticResource GridViewStyle}"
SelectionMode="Multiple"
HorizontalContentAlignment="Stretch">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White"
BorderThickness="1"
BorderBrush="Gray">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Name, Mode=OneWay}"/>
<TextBlock Text="{Binding Creator, Mode=OneWay}"/> </StackPanel>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="0,0,0,20"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center"
MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Here is the render :
If you want the items to stack like this, you should be using a ListView instead. All you have to do is to remove the whole <GridView.ItemsPanel>...</GridView.ItemsPanel> code, change the GridView to ListView and TargetType="GridViewItem" to TargetType="ListViewItem".
It looks like you want a single-column GridView. Try to use a ListView instead, and remove the custom ItemsPanelTemplate from your code. In the ListView items will use all the width available.
Alternatively set the HorizontalAlignment="Stretch" in your ItemsWrapGrid.
I have a Grid column and I have a list view in it. I am populating it from a form which is found in a another column. The values entered in the form gets saved to a list. I want that list displayed in the list view. When the text entered in the form increases the remaining values gets disappeared. I want that column to scroll horizontally so the values don't get disappeared.
This is what I have tried so far..
<Grid Grid.Column="2" Margin="0,0,46,10" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ScrollViewer HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto" VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden" Margin="0,0,-60,10">
<ListView x:Name="lsvLessons" IsItemClickEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" BorderThickness="1" SelectionMode="Multiple" ItemsSource="{Binding Source={StaticResource cvsLessons}}" Margin="7,0,62,0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" HorizontalChildrenAlignment="left"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="-12"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" Width="375" Height="20" Background="Transparent" HorizontalAlignment="Left">
<StackPanel Width="230" VerticalAlignment="Center" Margin="15,5,0,0">
<TextBlock Text="{Binding Name}" Foreground="white" FontSize="14" Margin="0,3,0,0" FontWeight="Normal" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</Grid>
Someone please help me do this.
Any kind of help is appreciated....
Have you tried to do that w/o the ScrollViewer Control? and Enable the horizontal scroll mode?
Try this:
<Grid Grid.Column="2" Margin="0,0,46,10" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ListView x:Name="lsvLessons" IsItemClickEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" BorderThickness="1" SelectionMode="Multiple" ItemsSource="{Binding Source={StaticResource cvsLessons}}" Margin="7,0,62,0" ScrollViewer.HorizontalScrollMode="Enabled" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" HorizontalChildrenAlignment="left"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="-12"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" Width="375" Height="20" Background="Transparent" HorizontalAlignment="Left">
<StackPanel Width="230" VerticalAlignment="Center" Margin="15,5,0,0">
<TextBlock Text="{Binding Name}" Foreground="white" FontSize="14" Margin="0,3,0,0" FontWeight="Normal" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Adding ScrollViewer.HorizontalScrollMode="Enabled" & Removing the ScrollViewer control ..
UPDATE:
You can achieve that without using columns.. here's my try:
<Grid x:Name="rootGrid">
<ScrollViewer HorizontalScrollMode="Enabled" >
<StackPanel Orientation="Horizontal" >
<Grid x:Name="form" >
<!-- your form here.. -->
</Grid>
<Grid x:Name="list" >
<!-- your listview here.. -->
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
Good luck :)
I've created a new GridView that groups the item by key.
<GridView
Style="{StaticResource DefaultGridViewStyle}"
ItemsSource="{Binding Source={StaticResource TimeGroupCollectionViewSource}}"
ItemTemplate="{StaticResource TransactionDataTemplate}"
MaxHeight="{Binding MaximumContentHeight}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical" GroupHeaderPlacement="Left"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Border Background="{ThemeResource B2}" Height="40" VerticalAlignment="Top" Tapped="Border_Tapped">
<TextBlock Style="{StaticResource GroupTextBlockStyle}" Height="40" VerticalAlignment="Top" Text="{Binding Key}" />
</Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
<Page.Resources>
<CollectionViewSource x:Name="TimeGroupCollectionViewSource" IsSourceGrouped="True" Source="{Binding TransactionList}" ItemsPath="Data"/>
</Page.Resources>
That works fine. By default every group starts in a new column.
What I want is something like this:
How can I achieve that? Do I miss some properties?
If you want your grid to scroll vertically - you should try changing its ScrollViewer.HorizontalScrollMode and ScrollViewer.VerticalScrollMode or use a ListView with custom ItemsPanel.
My Gridview works well, but there is a problem i cant figure out since a while.
The Gridview displayes not more the 2 Items per group. The ItemTemplate and the incoming
List are valid.
<GridView x:Name="mainGridView" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="Multiple" IsItemClickEnabled="True" ItemClick="GridView_ItemClick_1" Grid.Row="1"
Margin="0,-3,0,0" Padding="116,25,40,46"
FontFamily="Global User Interface" ItemTemplate="{StaticResource mainPageTileTemplates}"
ItemContainerStyle="{StaticResource GridViewItemStyleStretch}" SelectionChanged="Item_selected" >
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text='{Binding Key}' Foreground="#FF116C15" Margin="5" FontSize="28" FontFamily="Segoe UI Light" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<StackPanel Orientation="Vertical">
<ContentPresenter Content="{TemplateBinding Content}" />
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding GroupItems}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" MaximumRowsOrColumns="5" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" MaximumRowsOrColumns="1" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<Button Visibility="Collapsed"/>
</GridView>
Maybe in your GroupItems collection you're binding the elements only to a Top collection that only contains the first 2 elements (as the template does, but with 12 elements on the Top). Check de Path of GroupItems.