UWP Grid do not fill parent container - c#

I've got a big problem and I can't figure out how to solve it. I have a xaml layout:
<Hub x:Name="MainHub" DataContext="{x:Bind Model}" Margin="108,30,0,0">
<Hub.Resources>
<DataTemplate x:Key="HeaderTemplate">
<TextBlock Text="{Binding}" FontSize="26" FontWeight="Light" Foreground="#4B5054"/>
</DataTemplate>
</Hub.Resources>
<HubSection Header="News">
<HubSection.HeaderTemplate>
<StaticResource ResourceKey="HeaderTemplate"/>
</HubSection.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,4,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<controls:VariableGridView x:Name="NewsGrid" Grid.Row="0" ItemsSource="{Binding News}">
<GridView.Resources>
<DataTemplate x:Key="NewsItemTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="188*" />
<RowDefinition Height="50*" />
<RowDefinition Height="57*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<controls:WebImage ImageUri="{Binding Image, Mode=OneWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
<Grid Background="#802A2B2D" Grid.Row="1">
<TextBlock Text="{Binding Title, Mode=OneWay}" Foreground="#D7D7D7" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
</Grid>
<Grid Background="White" Grid.Row="2">
<TextBlock Text="{Binding Text, Mode=OneWay}" Foreground="#2A2B2D" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
</Grid>
</Grid>
</DataTemplate>
</GridView.Resources>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid x:Name="TestGrid" Orientation="Vertical" MaximumRowsOrColumns="2"
ItemWidth="{Binding Width, ElementName=DummyNews, Mode=OneWay}" ItemHeight="{Binding Height, ElementName=DummyNews, Mode=OneWay}"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<StaticResource ResourceKey="NewsItemTemplate"/>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<Setter Property="Margin" Value="0 0 15 15"/>
</Style>
</GridView.ItemContainerStyle>
</controls:VariableGridView>
<TextBlock VerticalAlignment="Bottom" Grid.Row="2" HorizontalAlignment="Right" Text="More >" FontSize="26" FontWeight="Light" Margin="0,0,15,0" Foreground="#4B5054" />
</Grid>
</DataTemplate>
</HubSection>
<HubSection Header="Featured Products">
<HubSection.HeaderTemplate>
<StaticResource ResourceKey="HeaderTemplate"/>
</HubSection.HeaderTemplate>
<DataTemplate>
<Grid/>
</DataTemplate>
</HubSection>
</Hub>
I have VariableSizedWrapGrid's width and height bound to code-behind models (item size changes when I resize a window):
ItemHeightVM.Value = (e.NewSize.Height - 200) / 2;
ItemWidthVM.Value = ItemHeightVM.Value / NEWS_WH_ASPECT;
This part working, but grid, specified in VariableGridView's data template don't fill whole item:
Widht and height not specified, grid do not fill parent container
But when I bind grid's width and height to my code-behind VM, or just specify width and height values, I've got right item size and right layouting, but only if item's rowspan and colspan are 1:
<DataTemplate x:Key="NewsItemTemplate">
<Grid Width="{Binding Width, ElementName=DummyNews, Mode=OneWay}" Height="{Binding Height, ElementName=DummyNews, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="188*" />
<RowDefinition Height="50*" />
<RowDefinition Height="57*" />
</Grid.RowDefinitions>
When colspan or rowspan are 2 or more, margins are back :(
Bound to view model, colspan set to 2
Please, tell me how can I remove those margins and stretch my grid to fill whole item container if colspan (or rowspan) will be set to 2 or more? Hope that you can help me, I tried to solve this issue for a couple of hours and gave up

Related

Variable image height in Nested Grid UWP

I want to show multiple images one after one vertically. That's why I've implemented Nested grid. It works fine for same height images. but different height images it looks odd because in nested grid height set according to first item height. Here is my code:
<DataTemplate x:Key="ImageTemplate">
<Grid x:Name="ImageGridViewItem"
HorizontalAlignment="Center"
Padding="0,0,0,0"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Background="#FAFAFA"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderThickness="1">
<Image Source="{Binding ImageSource, Mode=OneWay}"
Stretch="Uniform"
Width="{Binding ImageSource.PixelWidth, Mode=OneWay}"
Height="{Binding ImageSource.PixelHeight, Mode=OneWay}"/>
</Grid>
<Grid Grid.Row="1"
Background="#F5F5F5"
Padding="0,0,0,0">
<TextBlock x:Name="ImageNoTxtBox"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="0,4,0,0"
Padding="0"
FontFamily="Segoe UI"
FontSize="10"
FontWeight="Normal"
Foreground="#252525"
Text="{Binding ImageNo,Mode=TwoWay}">
</TextBlock>
</Grid>
</Grid>
<GridView x:Name="ImagesGridView"
Grid.Row="5"
Margin="12,0,2,0"
Padding="10,10,0,0"
Width="{Binding MainGridViewWidth}"
ItemsSource="{Binding ImageList, Mode=OneWay}"
ItemTemplate="{StaticResource ImageTemplate}">
</GridView>
Image
As you mentioned, the row height of GridView depends on the first item, if you want to show the Variable height in GridView, you can try to use WrapPanel from Windows Community Toolkit. Before using it, you need to add Microsoft.Toolkit.Uwp.UI.Controls nuget package and then override the ItemsPanel of GridView, for example:
.xaml:
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
<GridView x:Name="ImagesGridView"
Grid.Row="5"
Margin="12,0,2,0"
Padding="10,10,0,0"
Width="{Binding MainGridViewWidth}"
ItemsSource="{Binding ImageList, Mode=OneWay}"
ItemTemplate="{StaticResource ImageTemplate}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<controls:WrapPanel Name="VerticalWrapPanel" Orientation="Vertical" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>

WPF - How do I get scollviewer to act proeprly?

I have a grid, and within that grid I have the following:
<TabControl Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3">
<TabItem Header="Weapons">
<ScrollViewer>
<DataGrid>
...
</DataGrid>
</ScrollViewer>
</TabItem>
</TabControl>
So, I have obviously taken out the stuff which isn't needed to show my problem. When the Datagrid fills up, the space it requires obviously grows. I intended this to fill down as far as it could go, and then the scrollviewer would do the rest. However, it seems to think it can have unlimited length, and the scrollviewer never actually scrolls.
I dont want to manually set a maxheight value, as there is moving content above the TabControl so it would change (plus window resizing etc). How would I get the scrollviewer to not expand further than the limits of the window / the parent grid to TabControl?
Condensed "full" xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="1">
<Image Source="{StaticResource EmptySlot}" Margin="0" Width="34"/>
<Image Source="{Binding AuraSlot, FallbackValue={StaticResource AuraSlot}}" Margin="0" Width="34"/>
</Grid>
<Popup AllowsTransparency="True" Placement="Relative" PlacementTarget="{Binding ElementName=MainWindowName}" IsOpen="{Binding WeaponTooltipOpen}" HorizontalOffset="{Binding WeaponOffsetX}" VerticalOffset="{Binding WeaponOffsetY}" PopupAnimation="Fade" OpacityMask="White" >
...
</Popup>
<Grid Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3">
<Expander orizontalAlignment="Center">
<Expander.Header>
<TextBlock Text="Equipment Slots" HorizontalAlignment="Center" />
</Expander.Header>
<Grid Grid.Row="0" Grid.Column="1">
...
</Grid>
</Expander>
</Grid>
<TabControl Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3">
<TabItem Header="Weapons">
<Grid>
<ScrollViewer CanContentScroll="True" >
<DataGrid Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" ItemsSource="{Binding GroupedWeapons}" AutoGenerateColumns="False" IsReadOnly="True" AlternatingRowBackground="Gainsboro" AlternationCount="2" RowHeaderWidth="0">
<DataGrid.GroupStyle>
<GroupStyle>
...
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
...
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
...
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</ScrollViewer>
</Grid>
</TabItem>
</TabControl>
</Grid>
If you need vertical scrollbar try this or change to horizontalScrollBar. And CanContentScroll Property to true.
<TabControl Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3">
<TabItem Header="Weapons">
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<StackPanel Orientation="Vertical">
<GridView>
...
</GridView>
</StackPanel>
</ScrollViewer>
</TabItem>
</TabControl>
try if it works, or update me back.
Just try using it With window height if you want of the size of window. it will expand till it gets to the size of window.

How to make the scrollviewer work in this scenario?

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.

How to add a border to UniformGrid cells

I'd like to add a border around elements in my WPF UniformGrid. What I've tried:
<Window.Resources>
<DataTemplate x:Key="GridCell">
<Border BorderBrush="DarkGray" BorderThickness="5"></Border>
</DataTemplate>
</Window.Resources>
...and...
<UniformGrid Name="grid">
<ItemsControl ItemTemplate="{StaticResource GridCell}"></ItemsControl>
</UniformGrid>
It doesn't work (no border appears). I'd like to have each child of the UniformGrid (buttons which are created programmatically, so they don't appear here) to have a border. It needs to look like, well, a grid... with horizontal and vertical gridlines delineating rows and columns.
<Grid>
<ItemsControl ItemsSource="{Binding NumericalPatches}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="7" Columns="7"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="DimGray" BorderThickness="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="5" Text="{Binding StringFormat=F4,Path=Red}" FontSize="14" Foreground="Red"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="5" Text="{Binding StringFormat=F4,Path=Green}" FontSize="14" Foreground="Green"/>
<TextBlock Grid.Row="1" Grid.Column="0" Margin="5" Text="{Binding StringFormat=F4,Path=Blue}" FontSize="14" Foreground="Blue"/>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="5" Text="{Binding StringFormat=F4,Path=Chroma}" FontSize="14" Foreground="White"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>

ItemsControl ScrollViewer return to initial position after scrolling

I am adding a ScrollViewer to ItemsControl whose ItemTemplate is generated dynamically.
The problem is the ScrollViewersnaps back to its initial position after scrolling. I tried setting the grid container Grid.Row="1" in which the ScrollViewer lies so that it has enough height or set it auto but the problem persist. What am I missing?
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding GameLevel, Converter={StaticResource EnumToStringConverter}}" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock HorizontalAlignment="Right" Grid.Column="1" Style="{StaticResource PhoneTextNormalStyle}">
<Run Text="GAME "/>
<Run Text="{Binding CurrentGame}"/>
<Run Text=" / "/>
<Run Text="{Binding TotalGame}"/>
</TextBlock>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}">
<Run Text="{Binding CurrentTime, Converter={StaticResource SecondsToMinutesHour}}"/>
</TextBlock>
<TextBlock Foreground="Green" HorizontalAlignment="Right" Grid.Column="1" Margin="9,-7,9,0" Style="{StaticResource PhoneTextTitle2Style}">
<Run Text="{Binding TotalTime, Converter={StaticResource SecondsToMinutesHour}}"/>
</TextBlock>
<ProgressBar Grid.Row="1" Grid.ColumnSpan="2" x:Name="ProgressBar" Value="{Binding ProgressBarTime}" Minimum="0" Maximum="100" VerticalAlignment="Top" CacheMode="BitmapCache"/>
</Grid>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Tiles}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Tag="{Binding Index}" Loaded="FrameworkElement_OnLoaded">
<Button Width="{Binding Side}"
Height="{Binding Side}"
Background="{Binding BgColor}"
Tag="{Binding Index}"
Content="{Binding Index}"
FontSize="{StaticResource PhoneFontSizeSmall}"
Click="Button_Click">
<ia:Interaction.Triggers>
<ia:EventTrigger EventName="Loaded">
<tr:SetCanvasPropertiesAction Left="{Binding Left}" Top="{Binding Top}" />
</ia:EventTrigger>
</ia:Interaction.Triggers>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<Grid x:Name="adGrid" Grid.Row="2" HorizontalAlignment="Center"/>
</Grid>
edit:
Ok, the real problem is, that the ItemsPnaelTemplate is a Canvas. The canvas always has Height=0 and Width=0. Items that are placed in the canvas can be bigger, but are still inside the canvas. The scrollviewer only has the Height of the canvas as an idea on how much it should be able to scroll.
You can easily test this by temporarily setting the height of the canvas:
<ItemsPanelTemplate>
<Canvas Height="1500"/>
</ItemsPanelTemplate>
And you will see, that now you can scroll.
Unfortunately I can't think of a solution right now. (Maybe setting the width and height of the itemsControl through code behind by calculating the needed width and height to dispay all items, by taking the items with the highest value for (Top + Side) as Height and (Left + Side) for Width)
original:
Your ContentPanel Grid has this Height="Auto". So the ContentPanel is the same Height as the ScrollViewer and all of it's content and the actual scrolling that you can still do is just the bouncing effect of the ScrollViewer when you get to the end of it's scrolling ability.
Just delete Height="Auto" and you should be fine.

Categories