I'm trying to create a custom schedule for only one day( a single column) where the elements of the schedule are binded to an ObservableCollection :
public ObservableCollection<Content> ContentsToTransfer { get; set; }
For now I'm having such code :
<Grid HorizontalAlignment="Stretch" Margin="430,52,444,0" x:Name="grid1" VerticalAlignment="Stretch" Width="Auto" OpacityMask="Black" Opacity="1" Background="#FFC2ECEC" ShowGridLines="False" >
<Grid.Resources>
<Style x:Key="VerticalSeparatorStyle"
TargetType="{x:Type Separator}"
BasedOn="{StaticResource {x:Type Separator}}">
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="90"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Separator Grid.ColumnSpan="7" HorizontalAlignment="Stretch" Margin="0,132" x:Name="separator4" VerticalAlignment="Stretch" Width="Auto" Grid.Row="3" Grid.RowSpan="2" Background="Aqua" HorizontalContentAlignment="Stretch" Foreground="Aqua" OpacityMask="Aqua" />
<Separator HorizontalAlignment="Stretch" Margin="0,132" x:Name="separator2" VerticalAlignment="Stretch" Width="Auto" Background="Aqua" Grid.ColumnSpan="7" Grid.Row="1" Grid.RowSpan="2" HorizontalContentAlignment="Stretch" Foreground="Aqua" />
<Separator HorizontalAlignment="Stretch" x:Name="separator1" VerticalAlignment="Stretch" Background="Aqua" Grid.Row="2" Grid.ColumnSpan="7" Margin="0,129" Grid.RowSpan="2" HorizontalContentAlignment="Stretch" Foreground="Aqua" />
<Separator HorizontalAlignment="Stretch" Margin="0,128" x:Name="separator3" VerticalAlignment="Stretch" Background="Aqua" Grid.ColumnSpan="7" Grid.RowSpan="2" Width="Auto" HorizontalContentAlignment="Stretch" Foreground="Aqua" />
<Rectangle Height="Auto" HorizontalAlignment="Stretch" x:Name="rectangle1" Stroke="Aqua" VerticalAlignment="Stretch" Width="Auto" Grid.RowSpan="5" />
</Grid>
The thing I want to do now is to bind the ObservableCollection to that grid so each time a content is added to the ObservableCollection it appears on the grid as well.
I also want to add the behavior of a scheduler to it.
Can you help me out?
Am I doing it right?
Is there a best solution than doing that?
It is not possible to bind a collection to a Grid, as the grid is not an ItemsControl. You can however, bind the collection to a ListBox, or a ListView, or a WrapPanel and so on. In this scenario, I'd recommend using an ItemsControl, where the ItemsPanel is a StackPanel, here's how:
<ItemsControl ItemsSource="{Binding ContentsToTransfer}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- Your Template Here -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Inside your DataTemplate, you simply need to define what each Content will look like. For more information on DataTemplate, see the documentation
Related
I'm struggling with performance in my WPF application.
I have a ListView i populate with some buttons, which contain a bunch of TextBlocks with bindings.
I managed to get Virtualization going, so it seems the same whether its 20 or 2000 i load.
The problem is between 5 and 20. It simply appears that rendering a bunch of somewhat complicated User Controls, is simply too much for basic sub-par hardware.
This is how my Buttons/UserControls in my ListView looks ->
ListViewSample
I feel like WPF should be able to render this on sup-par hardware.
This is the xaml for the ListView:
<ListView ItemsSource="{Binding ButtonModels, IsAsync=True}"
Margin="0"
x:Name="ButtonsListView"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SnapsToDevicePixels="True"
Background="Transparent"
BorderThickness="0">
<ListView.Resources>
<Style TargetType="ScrollBar">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform CenterX="0" CenterY="0"
ScaleX="3" ScaleY="3" />
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<local:UniformGridPanel IsItemsHost="True" VerticalAlignment="Top" Height="Auto" Rows="4" Columns="{Binding Columns}" Margin="0">
</local:UniformGridPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Height="117" Width="Auto"
Margin="6,0,6,0"
x:Name="MasterButton"
Click="MasterButton_Click"
Visibility="{Binding IsVisible, Converter={StaticResource BoolToVis}}"
Template="{StaticResource ProductButtonTemplate}"
Padding="0">
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Here is the xaml for the Button template:
<ControlTemplate TargetType="{x:Type Button}" x:Key="ProductButtonTemplate">
<UserControl>
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="26"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="{Binding HeaderBrush}" CornerRadius="3,3,0,0">
<TextBlock VerticalAlignment="Center" FontSize="12"
Text="{Binding DisplayName}"
Foreground="{Binding FontIsWhite, Converter={StaticResource BoolToFontColour}}"
FontFamily="{StaticResource DefaultRegular}"
Padding="8,0,0,0"/>
</Border>
<Border Grid.Row="1" Background="{StaticResource LightGrey}" CornerRadius="0,0,4,4" BorderBrush="{StaticResource BorderGrey}" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0"
FontSize="12" TextTrimming="CharacterEllipsis" Text="Nr.:"
FontFamily="{StaticResource DefaultFont}"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
Foreground="{StaticResource Black}"
Padding="8,0,0,0"/>
<TextBlock Grid.Row="1" Grid.Column="0"
FontSize="10" TextTrimming="CharacterEllipsis" Text="{Binding Combinations}"
FontFamily="{StaticResource DefaultFont}"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
Foreground="{StaticResource Black}"
Padding="8,0,0,0"/>
<TextBlock Grid.Row="2" Grid.Column="0"
FontSize="10" TextTrimming="CharacterEllipsis" Text="{Binding SizeAndColour}"
FontFamily="{StaticResource DefaultFont}"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
Foreground="{StaticResource Black}"
Padding="8,0,0,0"/>
<Grid Grid.Row="3" Grid.Column="0"
Width="24" Height="24"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="8,0,0,0"
Visibility="{Binding ShowStockValue, Converter={StaticResource BoolToVis}}">
<Ellipse Fill="{Binding StockStatus, Converter={StaticResource EnumToBrush}}" Stroke="{StaticResource LightGrey}" StrokeThickness="0.1">
</Ellipse>
<TextBlock Text="{Binding Stock}"
Foreground="{StaticResource White}"
FontSize="9"
FontFamily="{StaticResource DefaultFont}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
<TextBlock Grid.Row="0" Grid.Column="1"
FontSize="12" TextTrimming="CharacterEllipsis" Text="{Binding ProductNr}"
Foreground="{StaticResource Black}"
VerticalAlignment="Center" HorizontalAlignment="Right"
FontFamily="{StaticResource DefaultFont}"
Padding="0,0,8,0"/>
<Label Grid.Row="3" Grid.Column="1" FontSize="13"
Padding="0,0,8,8"
Content="{Binding Price}"
Foreground="{StaticResource Black}"
FontWeight="Bold"
FontFamily="{StaticResource DefaultFont}"
VerticalContentAlignment="Bottom" HorizontalContentAlignment="Right"
ContentStringFormat="{}{0:#,0.00}" />
</Grid>
</Border>
</Grid>
</UserControl>
</ControlTemplate>
tldr; I'm looking for performance tips on how to make this render faster. And this is BEFORE i reach a size in the ListView where my virtualization kicks in (Which works flawlessly)
Thanks in advance!
I managed to find a high performance solution - it just wasn't what i would expect to be better performing.
So instead of having one ListView with a binding, changing the data in the binding and repopulating the Listview, i just spawn a ListView for every collection i have.
It seems weird to me, that having a bunch of ListViews and just collapsing and showing them is more effcient, but it performs absolutely flawlessly.
GridSplitter getting stuck after dragging some pixels,and have to reselect the splitter and drag again.
I am using RadTreeView in one column, and ListBox in second column, in which user can select Item from ListBox and Drag it into RadTreeView.
Please find below screenshot for the UI.
I tried to find solution on SO, but not getting any useful answer.
Please find below code for the same, Let me know if you require more information for the same.
<UserControl x:Class="StructureDesigner.StructureDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:dragDrop="clr-namespace:Telerik.Windows.Controls.DragDrop;assembly=Telerik.Windows.Controls"
xmlns:vm="clr-namespace:StructureDesigner.ViewModel"
MinHeight="400" MinWidth="400" AllowDrop="True" telerik:DragDropManager.AllowCapturedDrag="True" Name="StructureDesignerScreen">
<UserControl.Resources>
<Style TargetType="telerik:RadTreeViewItem">
<Setter Property="AllowDrop" Value="true" />
<Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
<Setter Property="telerik:DragDropManager.AllowDrag" Value="True" />
</Style>
<Style TargetType="ListBoxItem">
<Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
</Style>
</UserControl.Resources>
<Grid x:Name="MainGrid" ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GridSplitter x:Name="gridSplitter" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Width="10" Background="DarkGray" Height="Auto" />
<telerik:RadTreeView x:Name="radStructureTreeView" IsDragTooltipEnabled="True" IsDragDropEnabled="True"
IsDragPreviewEnabled="True" IsDropPreviewLineEnabled="True"
Grid.Row="0" Grid.Column="0" SelectionMode="Extended"
HorizontalAlignment="Stretch" Margin="2,2,11,2" IsLoadOnDemandEnabled="True"
LoadOnDemand="radStructureTreeView_LoadOnDemand"
ExpanderStyle="{StaticResource ExpanderStyle}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
IsExpandOnSingleClickEnabled="False" ItemsSource="{Binding StructureDesignerList}"
ItemTemplate="{StaticResource NavigationTemplate}"
telerik:TreeViewSettings.DragDropExecutionMode="New"
>
</telerik:RadTreeView>
<Grid Grid.Row="0" Grid.Column="1" Name="gridEntities" HorizontalAlignment="Stretch" Margin="1,2,2,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox x:Name="listBox1" Grid.Row="0" Grid.Column="0" Margin="8" HorizontalAlignment="Stretch"
SelectionMode="Extended" Width="Auto" ItemsSource="{Binding EntityList}"
AllowDrop="True">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Hide posted entities" Tag="Hide posted entities" IsCheckable="True" IsChecked="{Binding Path=IsHidePostedEntitiesChecked}"></MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Label Name="lblSpacer1" Height="5"></Label>
<StackPanel Orientation="Horizontal">
<Image Grid.Column="1" Width="25" Height="16" Source="{Binding Path=Icon}" VerticalAlignment="Top"></Image>
<Label Content="" Width="1" Height="16" ></Label>
<TextBlock Text="{Binding Description}" FontWeight="Bold" VerticalAlignment="Center" />
</StackPanel>
<Label Name="lblSpacer2" Height="5"></Label>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</UserControl>
Having some problems with my MVVM Application.
So the scenario is the following:
In my MainWindow.xaml, I have a ContentControl placed in a Grid Column, its content is bind to the CurrentViewModel which will be rendered to the appropriate View (in this case, Overview.xaml).
<ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding CurrentViewModel}">
Within this particular view (Overview.xaml) there are multiple UserControls placed within a StackPanel.
<ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<StackPanel CanVerticallyScroll="True" CanHorizontallyScroll="True">
<views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
<views:IncomeCollectionView DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
<views:ExpenseCollectionView DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
<views:CheckCollectionView DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" />
<views:BalanceCollectionView DataContext="{Binding Path=BalancesViewModel, Source={StaticResource Locator}}" />
<views:VacationCollectionView DataContext="{Binding Path=VacationsViewModel, Source={StaticResource Locator}}" />
<views:KHCollectionView DataContext="{Binding Path=KhViewModel, Source={StaticResource Locator}}" />
<views:OctaviaCollectionView DataContext="{Binding Path=OctaviaViewModel, Source={StaticResource Locator}}" />
</StackPanel>
</ScrollViewer>
Each UserControl within this StackPanel has a very similar look (obviously there are more stuff in the XAML). There is no constant value regarding Width or Height within my application.
<ListView ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Items[0].CurrentCategory}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="12" Rows="1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding EncryptedAmount}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Got paid on " />
<TextBlock Text="{Binding Date}" />
</StackPanel>
<Button Content="details"
Command="{Binding Path=DataContext.ShowDialogCommand,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="QuickEdit"/>
<Button Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The problem is that I can't seem to make the vertical scrollviewer work. It is displayed because I make it visible, but it's disabled. Obviously the StackPanel is gonna grow indefintely, but isn't there a way for it to calculate how much space is needed? Because most of the content is just cut off right now.
So I tried to put scrollviewer in every possible place, but they're all disabled.
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<ScrollViewer>
<ContentPresenter Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So then I tried dropping the StackPanel implementation and tried it with a Grid.
Nope, it doesn't work either.
Obviously I'm missing some basis solution here, but just can't figure it out.
Any ideas would be appreciated, seems like a very common scenario to be honest.
Cheers
<ScrollViewer CanContentScroll="True"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
<views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
<views:ExpenseCollectionView Grid.Row="2" DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
<views:CheckCollectionView Grid.Row="3" DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" />
...etc...
</Grid>
</ScrollViewer>
Edit: The DiagramView UserControl contains the following:
<UserControl x:Class="Expense.Manager.WPF.Views.DiagramView"
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:pie="clr-namespace:Expense.Manager.WPF.CustomPie"
xmlns:local="clr-namespace:Expense.Manager.WPF.Shared"
mc:Ignorable="d">
<UserControl.Resources>
<local:BoolToBrushConverter x:Key="BoolToBrushConverter" />
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Income this month: " />
<TextBlock>
<TextBlock.Text>
<PriorityBinding FallbackValue="Retrieving data...">
<Binding Path="EncryptedCurrentMonthIncome" Mode="TwoWay" IsAsync="True" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<pie:PieChart Data="{Binding PieChartIncomeData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Expenses this month: " />
<TextBlock>
<TextBlock.Text>
<PriorityBinding FallbackValue="Retrieving data...">
<Binding Path="CurrentMonthExpense" Mode="TwoWay" IsAsync="True" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<pie:PieChart Data="{Binding PieChartExpenseData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
</StackPanel>
<StackPanel Grid.Column="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding VacationsLeft}" />
<TextBlock Text=" days left" />
</StackPanel>
<ItemsControl ItemsSource="{Binding VacationsPerYearCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Margin="5, 0, 0, 0" Height="25" Width="4" Fill="{Binding Converter={StaticResource BoolToBrushConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Bank savings:" />
<TextBlock Text="{Binding BankSavings}" />
</StackPanel>
</StackPanel>
</Grid>
IncomeCollectionView:
<UserControl x:Class="Expense.Manager.WPF.Views.IncomeCollectionView"
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:views="clr-namespace:Expense.Manager.WPF.Views"
mc:Ignorable="d">
<UserControl.Resources>
<CollectionViewSource x:Key="groupedCollection" IsLiveGroupingRequested="True" Source="{Binding Collection}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="CurrentCategory" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding DisplayName}" Foreground="White" FontWeight="SemiBold" Padding="5" Background="SteelBlue" />
<ListView Grid.Row="1" ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Items[0].CurrentCategory}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Columns="12" Rows="1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding EncryptedAmount}" />
<TextBlock Grid.Row="1" Text="{Binding Date}" />
<Button Grid.Row="2" Content="details"
Command="{Binding Path=DataContext.ShowDialogCommand,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="QuickEdit"/>
<Button Grid.Row="3" Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
and where it is used:
why is the listview not resizing itself after resizing the window itself?
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
</Grid>
</ScrollViewer>
I tried dropping the StackPanel implementation and tried it with a Grid. Nope, it doesn't work either.
That's almost correct, apart from the last sentence. Using a Grid is half of the answer, because the StackPanel has no functionality to resize its items... you just need to inform the ScrollViewer when to scroll. Take this example:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Rectangle Fill="Cyan" />
<Rectangle Grid.Row="1" Fill="Green" />
<Rectangle Grid.Row="2" Fill="Red" />
<Rectangle Grid.Row="3" Fill="Blue" />
<Rectangle Grid.Row="4" Fill="Orange" />
<Rectangle Grid.Row="5" Fill="Purple" />
<Rectangle Grid.Row="6" Fill="Yellow" />
</Grid>
</ScrollViewer>
This XAML will make the ScrollViewer ScrollBar appear (once the Window.Height is small enough), but if you remove the RowDefinition.Height values (thereby giving each row a proportion of the whole Grid.Height), you'll see your previous situation where no ScrollBar appears.
Now, none of us want to hard code constant values into our UIs, but you can do this using the Auto setting on the RowDefinition.Height properties instead. Unlike these Rectangles, your controls will all have some Height, so your solution is to set each of your Grid.RowDefinitions like this:
<RowDefinition Height="Auto" />
This will provide your controls with as much space as they need within the Grid and therefore (hopefully) they will have more Height together than the ScrollViewer and therefore the ScrollViewer will display its vertical ScrollBar.
I have a problem with my ListBox. I have written several DataTemplates which I use in a ListBox. Each one of these contains a grid and may contain a nested ListBox depending on the item.
My problem is: The height of these nested ListBoxes seem to be different to the root ListBox's height. Additionally it seems, that there is sometimes one pixel margin to the element above.
Has someone encountered this problem, too and maybe solved it?
XAML-Code:
<!-- Template for SubData-Items -->
<DataTemplate x:Key="DataTemplate">
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999" Background="Violet">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
<Line Grid.ColumnSpan="999" Stroke="Black" X1="0" X2="{Binding ElementName=baseGrid, Path=ActualWidth, Mode=OneWay}" Y1="0" Y2="0" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
<!-- Template for Items -->
<DataTemplate x:Key="GroupDataTemplate">
<Grid Grid.ColumnSpan="999" Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Gantt, Path=GridRowHeight}" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
</Grid>
<Grid x:Name="expandedGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999">
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="0,0,2,0"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
</Grid>
</Grid>
</DataTemplate>
<!-- Grid with ListBox -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="Row0" Height="34"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" Width="25" />
<ColumnDefinition x:Name="Col1" Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999" ItemsSource="{Binding ItemSource, Mode=OneWay}"
ItemTemplate="{StaticResource GroupDataTemplate}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto"
ScrollViewer.CanContentScroll="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
FontSize="10" />
</Grid>
qqbenq gave a very nice solution . Here is another way to do it.
the control templates of ListBox and ListBoxItem has padding inside their borders. Thankfully ListBoxItem border's padding can be control by a style like so:
<Style
TargetType="ListBoxItem">
<Setter
Property="Padding"
Value="0" />
</Style>
but unfortunately for the ListBox , you will have to override the default template with all of its details to change its internal border's hard-coded padding like this:
<Style
TargetType="ListBox">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="0"
SnapsToDevicePixels="true">
<ScrollViewer
Focusable="false"
Padding="{TemplateBinding Padding}">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger
Property="IsEnabled"
Value="false">
<Setter
Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger
Property="IsGrouping"
Value="true">
<Setter
Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
One last note : remove the Margin that you added inside your xaml.
Solution complete
Add a Margin="-2,0,0,0" and a Padding="-1" to your "LBMaGruppen" named ListBox.
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="-2,0,0,0" Padding="-1"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
Also, the "root" element's height is binded to {Binding ElementName=Gantt, Path=GridRowHeight}, while the "sub" element's height to {Binding ElementName=Row0, Path=Height}, so this must cause the difference.
It seems that you have auto height set on all your ListBox. You could try setting the height to a specific size. EDIT: I see you already have ScrollViewer settings. I think setting the height of the box to a specific size instead of auto will do what you want.
As to the padding between elements see the ListBox.ItemContainerSyle which should allow you to set the margin between elements.
I need to layout my listbox like on this picture
I have tried everything to do that both for listbox and longlistselector..
<ListBox WP7Panels:DockPanel.Dock="Bottom" Name="MsgControlsList"
ItemsSource="{Binding}"
Height="600"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Bottom" VerticalContentAlignment="Bottom">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="VerticalAlignment"
Value="Bottom" />
<Setter Property="VerticalContentAlignment"
Value="Bottom" />
</Style>
</ListBox.Style>
<ListBox.ItemTemplate>
<DataTemplate>
<WP7Panels:DockPanel LastChildFill="True">
<HistoryClasses:HistoryElementTemplate WP7Panels:DockPanel.Dock="Bottom" VerticalAlignment="Bottom" DataContext="{Binding}" HorizontalContentAlignment="Stretch"/>
</WP7Panels:DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</WP7Panels:DockPanel>
..but still I have top vertical alignment of the listbox.
Any thoughts, please?
If you don't set the height of your listbox the items are on the bottom of the screen.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="600"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Test"/>
<ListBox Grid.Row="1" VerticalAlignment="Bottom">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="Item"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Grid.Row="2" Text="Test"/>
</Grid>