I have this code. For some reason I can't get the contentpresenter to stretch to fill the width of the canvas. Several of my attempts are commented out in the xaml.
<ItemsControl ItemsSource="{Binding MarkerLocations, Mode=OneTime}" HorizontalContentAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding}" />
<Setter Property="Canvas.Left" Value="0" />
<!--Setter Property="Width" Value="{Binding Path=Width, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas, AncestorLevel=1}}"/-->
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--Rectangle Stroke="Black" Height="2" Stretch="Fill"/-->
<Line Stretch="Fill" X2="2" Y1="{Binding Mode=OneTime}" Y2="{Binding Mode=OneTime}" Stroke="Black" StrokeThickness="1"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have a feeling I'm not understanding the context of the ItemContainters.
If you want to bind to the width of stretching objects you should bind to the ActualWidth:
{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Canvas}}
Edit: This may not be necessary
Canvases have the habit of not occupying any space at all unless you tell them:
<ItemsControl ItemsSource="{Binding MarkerLocations, Mode=OneTime}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Red"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Setting its Background is a useful "layout-debugging" trick to see if its actually there. From there one of your approaches should work.
Related
Here is an image of my problem and my code below. I'd like to know how I can get the text to be flipped right side up. Below is also a link where I got the suggestions for setting scale transform Y to 1.
https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-flip-a-uielement-horizontally-or-vertically
<Viewbox>
<Grid>
<ItemsControl ItemsSource="{Binding FaceParts}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="SlateBlue" Height="140" Width="80" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="RenderTransform" Value="1 0 0 -1 0 0"/>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Border Width="{Binding Width}" Height="{Binding Height}" Background="{Binding Fill}" BorderBrush="Black" BorderThickness=".20">
<Viewbox>
<TextBlock Text="{Binding TextOverlay}" RenderTransformOrigin=".5,.5">
<TextBlock.RenderTransform>
<ScaleTransform ScaleY="1"/>
</TextBlock.RenderTransform>
</TextBlock>
</Viewbox>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Viewbox VerticalAlignment="Bottom" Height="5" Margin="0,0,0,5">
<TextBlock Background="SlateBlue" TextAlignment="Center" Text="{Binding SelectedViewerProduct.Width, Converter={StaticResource FractionConverter}}"/>
</Viewbox>
</Grid>
</Viewbox>
As it turns out, setting ScaleY to a positive has no effect on flipping it right side up, in order to flip it right side up, I had to set the ScaleY to a -1. Essentially flipping it over again the opposite direction to make it right side up.
GroupBox has an auto column width. I can't think anymore why WidthConverter is not triggered when GroupBox has been resized. Any alternatives?
The goal is to display 5 rows and 5 columns always. When user resized the window, the column width must also resized. TIA!
<GroupBox Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="10" x:Name="GbSerial"
Template="{StaticResource GbSerialProgrammed}">
<GroupBox.Header>
<TextBlock TextDecorations="Underline" FontWeight="Bold" FontSize="24" HorizontalAlignment="Center" TextAlignment="Center"
Text="{lgg:Lgg Path=AllSerialNumberProgrammed}"/>
</GroupBox.Header>
<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
<ItemsControl x:Name="IcSerialNumbers" Background="White" Tag="{Binding ElementName=GbSerial, Path=ActualWidth}"
ItemsSource="{Binding AllSerialNumberProgrammed, UpdateSourceTrigger=PropertyChanged}"
helper:ItemsControlHelper.ScrollToLastItem="True"
FontSize="24" Height="250" >
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Height" Value="50"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Width" Value="{Binding ElementName=GbSerial,
Path=ActualWidth, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True,
Mode=OneTime, Converter={StaticResource WidthConverter},
ConverterParameter=5}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" FlowDirection="LeftToRight" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl >
</ScrollViewer>
</GroupBox>
Mode OneTime, as name implies, means it is invoked only once when it starts off.
I try to do a list of columns on a window and I want to have the same result than in a Grid when I use the *.
<ListView ItemsSource="{Binding UcColumns}"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Margin="0"
Orientation="Horizontal" Background="WhiteSmoke"
>
</WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
The problem is that the Wrappanel content width and height is depending of it proper content but not of the window size.
I hope you can help me.
Thx.
Try this:
<WrapPanel IsItemsHost="True" Margin="0" Orientation="Horizontal" Background="WhiteSmoke"
Width="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}, Mode=FindAncestor}}"
Height="{Binding ActualHeight,
RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}, Mode=FindAncestor}}">
I don't know why you want wrappanel here, but if you want your listviewitem content to stretch to the listview width then you can put the ListView.ItemContainerStyle like below:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
And set the itemtemplate like:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<local:MyuserControl HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
This will stretch your items
Thanks a lot for helping me.
I combinate your answer and with some other search I solve this problem as write under.
<ListView ItemsSource="{Binding UcColumns}"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate >
<uc:UC_Column HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="{Binding ActualWidth,
Converter={cv:DivideConverter},
ConverterParameter=3,
RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}, Mode=FindAncestor}}"
Height="{Binding ActualHeight,
RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}, Mode=FindAncestor}}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
One time again : thank you !
I'm trying to create a canvas, with items located at specefied locations on the canvast, as i can not bind an source and a template directly to a Canvas, have i used a ItemsControl.
But there are a problem all the items are located at 0,0. And i have tested the Bindings they do not return 0,0.
How can i make this work so the items are located at the right place?
Also is it poissible to create 2 layers on the canvas, where each layer is binded to a diffrent source, and uses a diffrent template?
This is in Silverlight
<ItemsControl Grid.Row="1" Grid.Column="1"
Width="650" Height="650"
ItemsSource="{Binding Skills}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Margin="0"
Width="650" Height="650" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Canvas.Top="{Binding Top}" Canvas.Left="{Binding Left}">
<TextBlock Text="{Binding Name}" />
<Image Source="{Binding Icon}" />
<StackPanel Orientation="Horizontal" >
<TextBlock FontWeight="Bold" TextAlignment="Center" Text="{Binding SkillPointsStatusText}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Test with ItemContainerStyle
<ItemsControl Grid.Row="1" Grid.Column="1"
Width="650" Height="650"
ItemsSource="{Binding Skills}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Margin="0"
Width="650" Height="650" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
<Image Source="{Binding Icon}" />
<TextBlock FontWeight="Bold" TextAlignment="Center" Text="{Binding SkillPointsStatusText}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Top}" />
<Setter Property="Canvas.Left" Value="{Binding Left}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Well i have droped the project, but i will leave the question open should one have an anwser
All of the following does not work in SL4 since it depends on bindings in a Setter.Value.
Try setting the binding in the ItemContainerStyle since your StackPanel is not the root element; your template will be placed in a ContentPresenter, so your attached properties for canvas positioning in the StackPanel will be ignored.
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Top}" />
<Setter Property="Canvas.Left" Value="{Binding Left}" />
</Style>
</ItemsControl.ItemContainerStyle>
Edit: If Silverlight does not support ItemContainerStyle you can set the universal style for ContentPresenters which should work just as well:
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.Resources>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
<Setter Property="Canvas.Top" Value="{Binding Top}"/>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In WPF, you can create a ListBox with a Canvas as an ItemsPanel and position items on that canvas. The code to do that looks something like this:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="200" Height="200"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Can you do the same thing in a Silverlight2 ListBox, or preferably an ItemsControl?
I've found a solution, but (to me) it smells.
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Width="200" Height="200">
<TextBlock
Text="{Binding Path=Name}"
Canvas.Left="{Binding Path=XPos}"
Canvas.Top="{Binding Path=YPos}" />
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="200" Height="200"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Each item has its own canvas, so they end up stacked on top of eachother.