How to add headers in WPF ListBox - c#

How does one add a header in a ListBox in WPF? I have the below code and where the "Header - .." text is I'd like a header/group name of all the items below up to the next header:
<ListBox
x:Name="ItemsListBox"
Margin="0 16 0 16"
Style="{StaticResource MaterialDesignNavigationPrimaryListBox}">
<ListBox.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource MaterialDesignScrollBarMinimal}"/>
</ListBox.Resources>
Header - Config
<Separator/>
<ListBoxItem>Config menu 1</ListBoxItem>
<ListBoxItem>Config menu 2</ListBoxItem>
<ListBoxItem>Config menu 3</ListBoxItem>
<ListBoxItem>Config menu 4</ListBoxItem>
<ListBoxItem>Config menu 5</ListBoxItem>
<ListBoxItem>Config menu 6</ListBoxItem>
<ListBoxItem>Config menu 7</ListBoxItem>
Header - Tasks
<Separator/>
<ListBoxItem>Task menu 1</ListBoxItem>
<ListBoxItem>Task menu 2</ListBoxItem>
<ListBoxItem>Task menu 3</ListBoxItem>
<ListBoxItem>Task menu 4</ListBoxItem>
<ListBoxItem>Task menu 5</ListBoxItem>
<ListBoxItem>Task menu 6</ListBoxItem>
<ListBoxItem>Task menu 7</ListBoxItem>
<Separator/>
</ListBox>
Below is an example of what I'd like to achieve:
It doesn't neccesarily need to have icons with each listbox item, but mainly the headers like Options, User Settings and Administraton.
I'm only seeing other threads where people have multiple columns, but that creates two columns with different data and I would like to have 1 column but just add headers in bold and size higher font to separate the different menus from each other.
I'm using the MaterialDesign Theme for WPF - whether that is of any importance or relevance...
Thanks!
EDIT 1: As I haven't mentioned before - it doesn't have to be a ListBox, I used it as it is used in the code I used to write my menu:
<materialDesign:DrawerHost
IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}">
<materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel MinWidth="220">
<ToggleButton
Style="{StaticResource MaterialDesignHamburgerToggleButton}"
DockPanel.Dock="Top"
HorizontalAlignment="Right"
Margin="16"
IsChecked="{Binding ElementName=MenuToggleButton, Path=IsChecked, Mode=TwoWay}"/>
<TextBox
x:Name="DemoItemsSearchBox"
Text="{Binding SearchKeyword, UpdateSourceTrigger=PropertyChanged}"
DockPanel.Dock="Top"
Margin="16, 4"
Width="200"
materialDesign:HintAssist.Hint="Search"
materialDesign:HintAssist.IsFloating="True"
materialDesign:TextFieldAssist.HasClearButton="True"
materialDesign:TextFieldAssist.HasOutlinedTextField="True"
materialDesign:TextFieldAssist.DecorationVisibility="Collapsed"
materialDesign:TextFieldAssist.TextFieldCornerRadius="4"/>
<ListBox
x:Name="ItemsListBox"
Margin="0 16 0 16"
Style="{StaticResource MaterialDesignNavigationPrimaryListBox}">
<ListBox.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource MaterialDesignScrollBarMinimal}"/>
</ListBox.Resources>
-- This is where the ListBox items would be --
</ListBox>
</DockPanel>
</materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel>
<materialDesign:ColorZone
Padding="16"
materialDesign:ShadowAssist.ShadowDepth="Depth2"
Mode="PrimaryMid"
DockPanel.Dock="Top">
<DockPanel>
<StackPanel Orientation="Horizontal">
<ToggleButton
x:Name="MenuToggleButton"
Style="{StaticResource MaterialDesignHamburgerToggleButton}"
IsChecked="False"
Click="MenuToggleButton_OnClick"
AutomationProperties.Name="HamburgerToggleButton"/>
</StackPanel>
<materialDesign:PopupBox
DockPanel.Dock="Right"
PlacementMode="BottomAndAlignRightEdges"
StaysOpen="False">
<StackPanel>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
Text="Light"
Margin="0 0 10 0"/>
<ToggleButton
x:Name="DarkModeToggleButton"
Click="MenuDarkModeButton_Click"
Grid.Column="1"/>
<TextBlock
Text="Dark"
Margin="10 0 0 0"
Grid.Column="2"/>
<TextBlock
Text="Enabled"
Margin="0 10 10 0"
Grid.Row="1"/>
<ToggleButton
x:Name="ControlsEnabledToggleButton"
Margin="0 10 0 0"
IsChecked="{Binding ControlsEnabled}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<Separator/>
<Button
Content="Hello World"
/>
<Button
Content="Nice Popup"
/>
<Button
Content="Can't Touch This"
IsEnabled="False"/>
<Separator/>
<Button
Content="Goodbye"
/>
</StackPanel>
</materialDesign:PopupBox>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="22"
Margin="-152,0,0,0"
Text="Hi"/>
</DockPanel>
</materialDesign:ColorZone>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer
x:Name="MainScrollViewer"
Grid.Row="1"
materialDesign:ScrollViewerAssist.IsAutoHideEnabled="True"
HorizontalScrollBarVisibility="{Binding SelectedItem.HorizontalScrollBarVisibilityRequirement, FallbackValue=Disabled}"
VerticalScrollBarVisibility="{Binding SelectedItem.VerticalScrollBarVisibilityRequirement, FallbackValue=Disabled}" >
<ContentControl
Margin="{Binding MarginRequirement, FallbackValue=16}"/>
</ScrollViewer>
<materialDesign:Snackbar
x:Name="MainSnackbar"
MessageQueue="{materialDesign:MessageQueue}"
Grid.Row="1"/>
</Grid>
</DockPanel>
</materialDesign:DrawerHost>

For a hardcoded xaml, non-MVVM solution, I would use a Menu instead of a ListBox. I generally only use ListBoxes for binding to lists of data/items.
We can also achieve your icons with this method.
Obviously, style to your liking, but if you take out your ListBox, you can replace with Menu as follows:
<ScrollViewer>
<Menu>
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<Menu.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource MaterialDesignScrollBarMinimal}"/>
</Menu.Resources>
<TextBlock Text="Config" FontWeight="Bold" FontSize="20" IsEnabled="False" />
<Separator/>
<MenuItem>
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 1" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 2" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 3" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 4" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 5" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 6" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem >
<MenuItem.Header>
<DockPanel>
<materialDesign:PackIcon Kind="Settings" Margin="3" />
<TextBlock Text="Config item 7" Margin="3" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
<TextBlock Text="Tasks" FontWeight="Bold" FontSize="20" />
<Separator/>
<MenuItem Header="Task item 1" />
<MenuItem Header="Task item 2" />
<MenuItem Header="Task item 3" />
<MenuItem Header="Task item 4" />
<MenuItem Header="Task item 5" />
<MenuItem Header="Task item 6" />
<MenuItem Header="Task item 7" />
</Menu>
</ScrollViewer>
This produces (I have only added icons to the top half, to illustrate how):

Probably not my Final answer, as still uses the MVVM from the demo, but using the demo project:
in the MainWindowViewModel.cs, add public ListCollectionView DemoLCV { get; } after public ObservableCollection<DemoItem> DemoItems { get; }
and add
DemoLCV = new ListCollectionView(DemoItems);
DemoLCV.GroupDescriptions.Add(new PropertyGroupDescription("Name"));
after
MoveNextCommand = new AnotherCommandImplementation(
_ =>
{
if (!string.IsNullOrWhiteSpace(SearchKeyword))
SearchKeyword = string.Empty;
SelectedIndex++;
},
_ => SelectedIndex < DemoItems.Count - 1);
then in the MainWindow.xaml amend the ListBox to:
<ListBox
x:Name="DemoItemsListBox"
Margin="0 16 0 16"
SelectedIndex="{Binding SelectedIndex}"
SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding DemoLCV}"
PreviewMouseLeftButtonUp="UIElement_OnPreviewMouseLeftButtonUp"
AutomationProperties.Name="DemoPagesListBox"
Style="{StaticResource MaterialDesignNavigationPrimaryListBox}">
<ListBox.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource MaterialDesignScrollBarMinimal}"/>
</ListBox.Resources>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="domain:DemoItem">
<TextBlock Text="{Binding Name}" Margin="24 4 0 4" AutomationProperties.AutomationId="DemoItemPage"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This adds the menu item name as a category heading for each item.
This is just to demonstrate the concept.
to expand on the idea, with useful headings, add another property to the DemoItem class, e.g. categoryName, and populate this with the different categories on initialisation of the DemoItems collection.
Then change DemoLCV.GroupDescriptions.Add(new PropertyGroupDescription("Name")); in this example to DemoLCV.GroupDescriptions.Add(new PropertyGroupDescription("categoryName")); to group by your categories.
You can then play with the style of the TextBlock in the ListBox.GroupStyle to display the heading as desired.
I'll try and pop in an example later, plus see if I can come up with a non-MVVM option.

Related

Some controls wont resize with window properly, statusbar creates whitespace for no reason i understand yet

I need to glue content to window sides, would also like to add a gridsplitter to resize internal control separation, and the status bar creates whitespace.
The Grid won't resize vertically with the bottom of the window for instance.
Currently, I am yet unaware of the cause or resolution, starting to go blind on the code. I could use a second pair of eyes.
Change Heights into MinHeights, use Grid containers, etc.
Pretty much anything I could find and think of, including staring down the code...
<Window x:Class="Teachers_Lounge.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Teachers_Lounge"
mc:Ignorable="d"
Title="Teachers Lounge"
Height="625"
Width="1525"
MinHeight="625"
MinWidth="1525"
KeyDown="Window_KeyDown"
Closing="Window_Closing" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="CalendarTemplate">
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="265" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0">
<TextBlock FontWeight="Bold" Text="Name:" DockPanel.Dock="Left" Margin="5,0,10,0" />
<TextBlock Text="" />
<TextBlock Text="{Binding EventName}" Foreground="Green" FontWeight="Bold" />
</DockPanel>
<DockPanel Grid.Row="1" Grid.Column="0">
<TextBlock FontWeight="Bold" Text="Date:" Foreground="DarkGray" DockPanel.Dock="Left" Margin="5,0,5,0" />
<TextBlock Text="{Binding EventDateTime}" />
</DockPanel>
<Grid Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="-5,0,5,0">
<Button x:Name="EditEvent_Button" Width="40" Height="15" Margin="0,5,0,0" VerticalAlignment="Top" BorderThickness="0" Background="LightGray" CommandParameter="{Binding}" Command="{Binding ElementName=Window, Path=OnClickEditEvent}" Click="EditEvent_Button_Click">
<TextBlock Margin="0, -2">Edit</TextBlock>
</Button>
<Button x:Name="DeleteEvent_Button" Width="40" Height="15" Margin="0,20,0,5" VerticalAlignment="Bottom" BorderThickness="0" Background="LightGray" CommandParameter="{Binding}" Command="{Binding ElementName=Window, Path=OnClickDeleteEvent}" Click="DeleteEvent_Button_Click">
<TextBlock Margin="0, -2">Delete</TextBlock>
</Button>
</Grid>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid MinHeight="586" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="360" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox x:Name="DateAndTime" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Height="30" Margin="10,10,0,0" TextWrapping="Wrap" Text="dddd dd mmmm HHh" VerticalAlignment="Top" Width="350" FontSize="20" IsEnabled="False"/>
<TextBox x:Name="Topic" Grid.Row="0" Grid.Column="1" Margin="10,10,77,10" TextWrapping="Wrap" Text="Topic" FontSize="20" FontWeight="Bold" KeyDown="Topic_KeyDown" LostFocus="Topic_LostFocus" />
<Button x:Name="Settings_Button" Grid.Column="1" Margin="0,10,10,10" FontWeight="Bold" Click="Settings_Button_Click" HorizontalAlignment="Right" Width="62">Settings</Button>
<Grid Grid.Row="1" Grid.Column="0"
Margin="10,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="489*" />
<RowDefinition Height="7*"/>
</Grid.RowDefinitions>
<Menu BorderThickness="1 1 1 0" BorderBrush="Black">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="New Event" Click="NewReplacement_Click" />
</Menu>
<ListBox x:Name="CalendarList" Grid.Row="1"
BorderThickness="1 0 1 1" BorderBrush="Black"
HorizontalAlignment="Left" MinWidth="350" MinHeight="485" VerticalAlignment="Top"
ItemsSource="{Binding Tables[0]}" ItemTemplate="{StaticResource CalendarTemplate}" KeyDown="CalendarList_KeyDown"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left" MinHeight="485" MinWidth="1072" VerticalAlignment="Top" Margin="10,0,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu BorderThickness="1 1 1 0" BorderBrush="Black">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="🠜" Click="ExcelPreviousDate_Click" />
<MenuItem Header="🡄" Click="ExcelPreviousWeek_Click" />
<MenuItem x:Name="ExcelActiveTimewindow" Header="Week XX, Date dd-MM-yy" IsEnabled="False" />
<MenuItem Header="🡆" Click="ExcelNextWeek_Click" />
<MenuItem Header="🠞" Click="ExcelNextDate_Click" />
<Separator />
<MenuItem Header="New Replacement" Click="NewReplacement_Click" />
<MenuItem Header="Delete Replacements" HorizontalAlignment="Right" Click="DeleteReplacements_Click" />
</Menu>
<DataGrid Name="ExcelDataView" Grid.Row="1"
BorderThickness="1 0 1 1" BorderBrush="Black"
AutoGenerateColumns="False"
ColumnWidth="*"
RowBackground="WhiteSmoke"
Background="LightBlue"
CanUserAddRows="False"
BeginningEdit="ExcelDataView_BeginningEdit"
CellEditEnding="ExcelDataView_CellEditEnding"
RowEditEnding="ExcelDataView_RowEditEnding"
SelectionChanged="ExcelDataView_SelectionChanged"
MinWidth="1077" MinHeight="485" HorizontalAlignment="Left" VerticalAlignment="Top">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<EventSetter Event="Click" Handler="OnExcelHeaderClicked" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Time" Binding="{Binding TimeText, Mode=TwoWay}" Width="70" CanUserSort="False" />
<DataGridTextColumn Header="Replaced User" Binding="{Binding ReplacedUser, Mode=TwoWay}" Width="140" CanUserSort="False" />
<DataGridTextColumn Header="Replacement User" Binding="{Binding ReplacementUser, Mode=TwoWay}" Width="140" CanUserSort="False" />
<DataGridTextColumn Header="Class" Binding="{Binding Class, Mode=TwoWay}" Width="170" CanUserSort="False" />
<DataGridTextColumn Header="Location" Binding="{Binding Location, Mode=TwoWay}" Width="170" CanUserSort="False" />
<DataGridTextColumn Header="Info" Binding="{Binding AdditionalInfo, Mode=TwoWay}" CanUserSort="False" />
<DataGridCheckBoxColumn Header="Mark" Binding="{Binding Marked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" CanUserSort="False" Width="50">
<DataGridCheckBoxColumn.CellStyle>
<Style>
<EventSetter Event="CheckBox.Checked" Handler="OnExcelDeleteColumnChecked"/>
<EventSetter Event="CheckBox.Unchecked" Handler="OnExcelDeleteColumnUnchecked"/>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
<Menu Grid.Row="3" Grid.ColumnSpan="2"
BorderThickness="0 1 0 0" BorderBrush="Black" IsEnabled="False"
VerticalAlignment="Bottom" Height="20">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem MinWidth="1111" BorderThickness="0">
<MenuItem.Header>
<TextBlock x:Name="StatusbarMessage"
HorizontalAlignment="Left" VerticalAlignment="Center"
TextAlignment="Left" />
</MenuItem.Header>
</MenuItem>
<MenuItem BorderThickness="0"
HorizontalAlignment="Right" HorizontalContentAlignment="Right" Width="350" >
<MenuItem.Header>
<TextBlock x:Name="StatusbarInfo"
VerticalAlignment="Center" Width="335"
TextAlignment="Right" />
</MenuItem.Header>
</MenuItem>
</Menu>
</Grid>
</Window>
A proper layout that resizes as it should is what I'd expect.
Some weird behavior and glue-ing are what is happening though.

One SelectedItem For Multiple Wpf Controls

I have a list box Bound to XML data correctly , but i have multiple Tree Views inside this listbox which you can select item for every one of them!
i want single item selecting from all of these tree views. which every one of those are inside an unique expander.
if you look at my xml data ,consider i have 2 groups inside xml , i can select item for both of those groups in listbox which now they are different treeviews in my ui , and i want single item selecting for all this listbox items.
<ListBox Background="Transparent" BorderThickness="0" SelectedValue="{Binding SelectedMenuValue,Mode=TwoWay}" ItemsSource="{Binding Path=Items,Source={StaticResource XmlSourceMenu}}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type revoxml:Group}">
<Expander Header="{Binding Title}">
<TreeView ItemsSource="{Binding Menus}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding}">
<StackPanel Orientation="Horizontal" Margin="10 0">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Expander>
</DataTemplate>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Orientation="Horizontal" Margin="10 0">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
for easier understanding data for this listbox comming from xml file like this :
<MainMenu>
<Group Title="title">
<SubMenu Icon="Inbox" Title="inbox" Tag="38"/>
<SubMenu Icon="CommentingOutline" Title="New Message" Tag="37"/>
<SubMenu Icon="Tachometer" Title="Archive" Tag="39"/>
<Menu Icon="CartArrowDown" Title="purchases" >
<SubMenu Icon="CartArrowDown" Title="new" Tag="26"/>
<SubMenu Icon="CartPlus" Title="list" Tag="28"/>
</Menu>
</Group>
<SubMenu Icon="InfoCircle" Title="info" Tag="6000" />
<SubMenu Icon="Close" Title="close" Tag="0"/>
</MainMenu>
this should solve it ! but you need to implement your own selected item, or you could change groupboxes to expander and items control to tree view to match your code
<Style TargetType="StackPanel" x:Key="HoverStackPanelStyle">
<Setter Property="Background" Value="Transparent"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
<ScrollViewer>
<HeaderedItemsControl Background="Transparent" ItemsSource="{Binding Path=Items,Source={StaticResource XmlSourceMenu}}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Orientation="Horizontal" Margin="10 0" Style="{StaticResource HoverStackPanelStyle}">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" FontFamily="{StaticResource nazanin}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type revoxml:Menu}" ItemsSource="{Binding Menus}">
<GroupBox Header="{Binding Title}" Margin="0 5">
<ItemsControl ItemsSource="{Binding Menus}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Name="StackPanel" Orientation="Horizontal" Margin="10 0" Style="{StaticResource HoverStackPanelStyle}">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" FontFamily="{StaticResource nazanin}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</GroupBox>
</HierarchicalDataTemplate>
</ItemsControl.Resources>
</HeaderedItemsControl>
</ScrollViewer>

wpf .net 4.5 Isvirtualizng when grouping updating list wrongly

i am binding a lot of images in listview using following code
lvImages.ItemsSource = lstVisualDuplicateImage;
following properties used in ListView
here is my complete XAML Binding ang Grouping is performed iam using .net 4.5
<ListView Name="lvImages" Margin="0,2,0,38"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.VirtualizationMode="Recycling" Grid.Row="1"
SelectionChanged="ListViewFiles_SelectionChanged"
ContextMenuOpening="ListViewFiles_ContextMenuOpening"
ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.RowSpan="3">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuOpen" Header="Open" Click="menuOpen_Click" />
<MenuItem x:Name="menuOpenFileLocation" Header="Open File Location" Click="menuOpenFileLocation_Click" />
<MenuItem x:Name="menuRemove" Header="Remove" Click="menuRemove_Click" />
<MenuItem x:Name="menuOpenProperties" Header="Properties" Click="menuOpenProperties_Click" />
</ContextMenu>
</ListView.ContextMenu>
<ListView.ItemsPanel>
<ItemsPanelTemplate >
<!--<VirtualizingStackPanel Orientation="Horizontal" >-->
<WrapPanel Orientation="Horizontal"/>
<!--</VirtualizingStackPanel>-->
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.View>
<GridView >
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Width="160" Header="Group Details" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border CornerRadius="2" BorderThickness="2" BorderBrush="#B3B4B5">
<StackPanel >
<StackPanel Orientation="Horizontal">
<CheckBox Margin="0" MinWidth="22" Name="chkSelRow" IsChecked="{Binding Path=Checked}" Unchecked="lvFileItem_UnChecked" Checked="lvFileItem_Checked" />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=size}" />
</StackPanel>
<Image Height="120" Width="120">
<Image.Source>
<BitmapImage
DecodePixelHeight="120"
DecodePixelWidth="120"
UriSource="{Binding Path=getUri, Mode=OneWay,UpdateSourceTrigger=Explicit }"
CreateOptions="IgnoreColorProfile"
CacheOption="None" />
</Image.Source>
</Image>
<StackPanel Orientation="Vertical">
<TextBlock Margin="5,0,0,3" Text="{Binding Path=FileName}" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True" Style="{DynamicResource newExpanderStyle}" >
<Expander.Header>
<StackPanel Orientation="Horizontal">
<Button Content="View Gropu" Style="{StaticResource LinkButton}" Foreground="Blue" Margin="10,5,0,0" x:Name="btnViewGroup" ></Button>
<TextBlock Text=" Group NO " FontSize="12" Foreground="Black" Margin="30,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="(" FontSize="14" Margin="0,2,0,0" Foreground="Black" />
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Black" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text=")" FontSize="14" Margin="0,2,0,0" Foreground="Black" />
<TextBlock Text=" Items in Group" FontSize="12" Foreground="Black" Margin="60,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="(" FontSize="14" Margin="0,2,0,0" Foreground="Black" />
<TextBlock Text="{Binding ItemCount}" FontSize="12" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text=")" FontSize="14" Margin="0,2,0,0" Foreground="Black" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
no of item is complete in listview
Problem is images repeat and change their position in groups not loading correctly and refreshing is there any way to virtualize groups.
You have changed the ListView.ItemsPanel from a VirtualizingStackPanel to a WrapPanel. Virtualization only works correctly when the panel supports virtualization. In this case, the standard WrapPanel does not support virtualization.

WPF ComboBox with CheckBox - Collapsed display value

I have a ComboBox that has an ItemTemplate with a CheckBox in it (read Dropdown CheckBoxList). I basically want to have a separate binding for the text in the combobox (both when an item is selected, and if an item isn't selected). I've tried a few different methods but either can't seem to get them to work with my setup, or can't find they have some issues. I've even tried a few mixes and matches of them. Usually I find they either don't work when an item isn't specifically selected (which could be possible if the user checks a few boxes then clicks out of the ComboBox), or aren't updating the text properly.
My xaml is this (the items of focus are the DataTemplates with the ComboBoxes in them):
<UserControl x:Class="BestClient.ucReportViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BestClient"
mc:Ignorable="d"
d:DesignHeight="315" d:DesignWidth="388" Background="#FFD7DFEC">
<UserControl.Resources>
<DataTemplate x:Key="datetime">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<DatePicker Tag="{Binding rfParameter}" SelectedDate="{Binding rfValues, Mode=TwoWay}" Width="200" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="office">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<ComboBox x:Name="officeComboBox" Tag="{Binding rfParameter}" Width="200" ItemsSource="{Binding Path=DataContext.OfficeList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}" VerticalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Tag="{Binding id}" IsChecked="{Binding isSelected}" Width="200" Content="{Binding value}" Margin="2" x:Name="CheckBox" Checked="OfficeCheckBox_Checked"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="carrier">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<ComboBox Tag="{Binding rfParameter}" Width="200" ItemsSource="{Binding Path=DataContext.CarrierList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}" VerticalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Tag="{Binding id}" IsChecked="{Binding isSelected}" Width="200" Content="{Binding value}" Margin="2"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="defaultTemplate">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<TextBox Tag="{Binding rfParameter}" Width="200" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
<local:ReportFilterTemplateSelector x:Key="ReportFilterTemplateSelector" />
</UserControl.Resources>
<Grid x:Name="ReportViewer">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="45"/>
<RowDefinition Height="*"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<Viewbox Grid.Row="0" Grid.Column="0">
<TextBlock Margin="10" TextWrapping="Wrap" Text="Select a Report:"/>
</Viewbox>
<ComboBox Grid.Column="1" Margin="10" Grid.ColumnSpan="2" ItemsSource="{Binding ReportList}" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedItem="{Binding SelectedReport}" VerticalContentAlignment="Center" />
<ListView x:Name="FilterList" Margin="10,0" Grid.Row="1" Grid.ColumnSpan="3" ItemTemplateSelector="{StaticResource ReportFilterTemplateSelector}" ItemsSource="{Binding reportFilters, Mode=TwoWay}" />
<Button Command="{Binding OpenReport}" Content="Open Report" Grid.Column="2" Margin="10" Grid.Row="2" VerticalAlignment="Stretch"/>
</Grid>
</UserControl>
Ideally, I'd like to bind the display text of the combobox with the OfficeListValues method in my ViewModel.
{Binding Path=DataContext.OfficeListValues, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}
Any help would be appreciated!

How do I cycle through records in an XML file using previous/next buttons?

I'm new to C# programming so here goes..
I'm trying to write an electronic scrapbook application as a present but I've come unstuck - my application currently shows the first xml record but I don't know how to use the next button to go to the next record. I've tried experimenting with arrays and arraylists but I can't seem to get anywhere near what I'm looking for. Any help would be hugely appreciated :-)
I'll include my XML and XAML code below but I'll leave out the C# code as it'll make my post too long. Apologies if any of the code below is irrelevant to you:
XAML:
<Grid>
<Grid.DataContext>
<XmlDataProvider Source="Data/Memories.xml" XPath="/Memories/Memory" />
</Grid.DataContext>
<DockPanel Height="22" Name="dockPanel1" HorizontalAlignment="Stretch" VerticalAlignment="Top" Width="Auto">
<Menu Height="24" Name="menu1" Width="Auto" DockPanel.Dock="Top" VerticalAlignment="Top">
<MenuItem Header="_File" >
<MenuItem Header="Add _New Memory" Name="newMemory" Click="newMemory_Click" />
<MenuItem Header="_Edit this Memory" Name="editMemory" Click="editMemory_Click" />
<MenuItem Header="_Delete this Memory" Name="deleteMemory" Click="deleteMemory_Click" />
<MenuItem Header="_Save Changes" Name="saveMemory" Click="saveMemory_Click" />
<Separator/>
<MenuItem Header="E_xit" Name="exit" Click="exit_Click" />
</MenuItem>
<MenuItem Header="_Edit" />
<MenuItem Header="_Help" >
<MenuItem Header="_About muh program" Name="about" Click="about_Click" />
</MenuItem>
</Menu>
</DockPanel>
<Button Content="<" Margin="-70,32,0,0" Name="previousButton" Height="22" Width="20" VerticalAlignment="Top" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfTrue}}" />
<Button Content=">" Height="22" Margin="70,32,0,0" Name="nextButton" Width="20" VerticalAlignment="Top" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfTrue}}" />
<Button Content="?" Margin="0,32,0,0" Name="RandomButton" Height="22" Width="40" VerticalAlignment="Top" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfTrue}}" />
<TextBlock Height="30" Width="300" Margin="0,62,0,419" TextAlignment="Center" Text="{Binding XPath=#Title}" FontSize="15" FontWeight="Bold" Name="memoryTitle" />
<TextBlock Height="30" Width="300" Margin="0,84,0,397" TextAlignment="Center" Text="{Binding XPath=./Date}" FontSize="12" FontWeight="Normal" Name="memoryDate" Panel.ZIndex="1" />
<TextBlock Height="375" HorizontalAlignment="Right" Margin="0,116,26,20" Name="textOutput" Width="300" TextWrapping="Wrap" TextAlignment="Center" Background="White" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfTrue}}">
<TextBlock.Text>
<Binding XPath="./Blurb" />
</TextBlock.Text>
</TextBlock>
<TextBox HorizontalAlignment="Right" Margin="0,116,26,20" Name="textInput" Height="375" Width="300" TextWrapping="Wrap" AcceptsReturn="True" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfNotTrue}}" />
<Image Height="375" HorizontalAlignment="Center" Margin="-326,94,0,0" Name="imgPhoto" Stretch="Uniform" VerticalAlignment="Center" Width="500" ClipToBounds="False" AllowDrop="False" Source="{Binding XPath=ImageFile}" />
<Image Height="375" HorizontalAlignment="Center" Margin="-326,94,0,0" Name="imgPhotoNew" Stretch="Uniform" VerticalAlignment="Center" Width="500" ClipToBounds="False" AllowDrop="False" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfNotTrue}}" />
<Button Content="Done" Height="22" Width="40" Margin="463,32,375,0" Name="doneMemoryButton" VerticalAlignment="Top" Click="doneMemoryButton_Click" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfNotTrue}}" />
<Button Content="Select Photo" Height="22" Width="75" Margin="377,32,427,0" Name="selectPhotoButton" VerticalAlignment="Top" HorizontalAlignment="Center" Click="selectPhotoButton_Click" Visibility="{Binding IsEnabled, ElementName=newMemory, Converter={StaticResource VisibleIfNotTrue}}" />
</Grid>
XML:
<Memories>
<Memory Title="1 Year - Howard Jones!" ID="1">
<ImageFile>Data/Images/01.jpg</ImageFile>
<Blurb>We saw Howard Jones perform!!</Blurb>
<Date>06/11/2010</Date>
</Memory>
<Memory Title="Ski Holiday" ID="2">
<ImageFile>Data/Images/02.jpg</ImageFile>
<Blurb>Our skiing holiday in Flaine!</Blurb>
<Date>29/11/2010</Date>
</Memory>
<Memory Title="Stinksy's Birthday: Ice Bar!" ID="3">
<ImageFile>Data/Images/03.jpg</ImageFile>
<Blurb>Absolut Ice Bar</Blurb>
<Date>19/12/2010</Date>
</Memory>
</Memories>
I will not work through that code but i can give you a simple example of how to do this:
<Window.Resources>
<XmlDataProvider x:Key="data" Source="Data/Memories.xml" XPath="/Memories/Memory" />
<CollectionViewSource x:Key="dataCvs" Source="{StaticResource data}" />
</Window.Resources>
<StackPanel>
<ContentControl Content="{Binding Source={StaticResource dataCvs}}">
<ContentControl.ContentTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding XPath=ImageFile}" />
<TextBlock Text="{Binding XPath=Blurb}" />
<TextBlock Text="{Binding XPath=Date}" />
</StackPanel>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
<Button Content="Previous" Click="Previous_Click" Tag="{StaticResource dataCvs}" />
<Button Content="Next" Click="Next_Click" Tag="{StaticResource dataCvs}" />
</StackPanel>
The ContentControl binds to the CurrentItem of the view on top of the memories collection, i pass the CollectionViewSource to the Buttons so i can change the current item on click. (Normally you should use a Command and pass it as CommandParameter instead, that is cleaner)
private void Next_Click(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
var cvs = (CollectionViewSource)button.Tag;
cvs.View.MoveCurrentToNext();
}
private void Previous_Click(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
var cvs = (CollectionViewSource)button.Tag;
cvs.View.MoveCurrentToPrevious();
}

Categories

Resources