Canvas binding in silverlight - wpf

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>

Related

How to bind Expander's IsExpanded property to Items.Count of Expander's Content as ItemsControl in Style

As the title says, i want to bind the property IsExpanded of my Expander to the Items.Count property of the ItemsControl, which is the Content of the Expander. I need this binding for more expanders so a style or something like that would be nice. I already tried some stuff found here or on other sites, but nothing worked.
Here is my actual code:
<Style x:Key="ExpanderStyleKey" TargetType="Expander">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Content.Items.Count}" Value="0">
<Setter Property="IsExpanded" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
Thank you for help!
EDIT:
Here is the code of one of my Expander:
<Expander Name="exp1"
Header="Expander1"
Style="{StaticResource ExpanderStyleKey}">
<ItemsControl Name="itcMain"
ItemsSource="{Binding Path=ListInCodeBehind, Mode=OneWay}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=ExampleProperty}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
Example,
<Expander>
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="IsExpanded" Value="{Binding Content.Items.Count, Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
</Style>
</Expander.Style>
<Expander.Content>
<ItemsControl>
<ItemsControl.Items>
<TextBlock Text="Item1"/>
<TextBlock Text="Item2"/>
<TextBlock Text="Item3"/>
</ItemsControl.Items>
</ItemsControl>
</Expander.Content>
</Expander>

WidthConverter is not trigger when GroupBox has been resize

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.

Stretch line to width of Itemstemplate canvas in itemscontrol

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.

Silverlight: Make the listbox background transparent?

I have a ListBox. It has a white background. How can I get rid of it?
Here is the XAML I'm trying. Whatever I do, I can't get rid of that background. (I'm not sure if it's on each item, which happen to take up all the space in the ListBox, or if it's on the background of the ListBox itself.)
<ListBox x:Name="topThreeHits" ItemsSource="{Binding TopThreeHits}" Margin="0,10,0,0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0" Background="Transparent">
<Image Source="{Binding Image, FallbackValue=/PlumPudding;component/Images/file.png}" />
<TextBlock>
<Run Text="{Binding Name, FallbackValue='File Name'}" FontWeight="Bold" />
<Run Text="." Foreground="#787878" FontWeight="Light" />
<Run Text="{Binding TypeExtension, FallbackValue='type'}" Foreground="#787878" FontWeight="Light" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm using Silverlight 4.
Your code is working fine, and properly setting the background style. I am assuming what you want to do is blow away the default item container completely so there is no background, including rollovers, etc.
The best way to do that is like this:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
I tried to add a Border around the ListBox with a Green Background and set the Background to Transparent for your ListBox and it seems to be working fine.
<Border Background="Green">
<ListBox x:Name="topThreeHits"
Background="Transparent"
ItemsSource="{Binding Customers}" Margin="0,10,0,0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0" Background="Transparent">
<Image Source="{Binding Image, FallbackValue=/PlumPudding;component/Images/file.png}" />
<TextBlock>
<Run Text="{Binding Name, FallbackValue='File Name'}" FontWeight="Bold" />
<Run Text="." Foreground="#787878" FontWeight="Light" />
<Run Text="{Binding TypeExtension, FallbackValue='type'}" Foreground="#787878" FontWeight="Light" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>

How do I use a Silverlight2 ItemsControl to position a collection of items on a canvas?

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.

Resources