WPF. How do I create several child controls via data-binding? - wpf

I have UserControl that includes several rectangles:
<StackPanel>
<Rectangle Height="70" Width="100" x:Name="Image1" />
<Rectangle Height="70" Width="100" x:Name="Image2" />
<Rectangle Height="70" Width="100" x:Name="Image3" />
</StackPanel>
How can I create various number of rectangles via data binding and set rectangles width and height (and other properties) instead of this static hardcode approach?
Thank you in advance!

Generally, you would have an ItemsControl (or a ListBox, etc.) and modify its item template to show the rectangles:
<ItemsControl ItemsSource={Binding MyRectangles}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Note that this assumes the data context has a MyRectangles collection, and each item within that collection has a Width and Height property.

Related

WPF ItemsControl with one stack of items

I need in ItemsControl that place all Items in the same position (0, 0), one stack, like a Grid by default if i will not set the Grid.Row and Grid.Column.
Yes i can use Grid or Canvas but maybe there is some other more primitive control? Or may be there are some styles changes to do so?
I want to bind the collection to ItemsSource as usual and rule the position of Items by their Margin properties. I have done offset logic but in standart ItemsControl the Margin of the second element is calculating from the end of the first what i want to avoid.
You could use a Grid as the ItemsPanel of the ItemsControl:
<ItemsControl>
<ItemsControl.Items>
<Rectangle Width="50" Height="50" Fill="Blue" />
<Rectangle Width="50" Height="50" Fill="Black" />
<Rectangle Width="50" Height="50" Fill="Yellow" Margin="10,10,0,0" />
</ItemsControl.Items>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
In the above example the items overlap each other as expected.

WPF Popup inside a DataTemplate

I need a WPF Popup inside a DataTemplate, something like this:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Collection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox Name="MyTextboxBrief" Text="{Binding TextBrief}"/>
<Popup PlacementTarget="{Binding ElementName=MyTextboxBrief}" Placement="Center">
<TextBox Name="MyTextboxVerbose" Text="{Binding TextVerbose}"/>
</Popup>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
But, this Popup should behave like this:
it must scroll together with relevant ItemsControl item
when app window is minimized - it shouldn't stay visible on desktop
it will be taller than ItemsControl, its content mustn't be clipped, but it mustn't change ItemsControl height
it will be wider than relevant ItemsControl item - but it shouldn't shift other ItemsControl items to the left or to the right
I have a strong feeling that I should somehow use ComboBox template - but I don't understand how to get it's Popup behavior
I don't think that Popup will help you here, nor ComboBox. See if this helps you any further:
<DataTemplate>
<Grid>
<TextBox Name="MyTextboxBrief" Text="{Binding TextBrief}" />
<!-- You might want to bind visibility against
some kind of property -->
<Canvas >
<Canvas.RenderTransform>
<!--In case you want to move-->
<TranslateTransform Y="-5" />
</Canvas.RenderTransform>
<Border Width="100" Height="20" Background="Black">
<TextBlock Text="Test" />
</Border>
</Canvas>
</Grid>
</DataTemplate>

How to change itemTemplate of an item in itemControl at runtime in silverlihgt 4

I have a ItemControl in silverlight 4 with a Canvas as a ItemPanel, the idea is to simulate a canvas area with drag and dop items.
ItemsControl has a ItemTemplate with a image and one button.
The idea is that when the button of itemTemplate Click the itemTemplate change.
Some of my code:
(Items Control)
<ItemsControl ItemsSource="{Binding Devices}"
ItemTemplate="{StaticResource deviceItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MouseLeftButtonDown="Canvas_MouseLeftButtonDown"
MouseMove="Canvas_MouseMove"
LostMouseCapture="Canvas_LostMouseCapture"></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
(ItemTemplate)
<DataTemplate x:Key="deviceItemTemplate">
<ContentControl>
<Grid IsHitTestVisible="True" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Image IsHitTestVisible="False" Grid.Row="0" Stretch="UniformToFill"
Width="50" Height="50"
Source="{Binding ImagePath}"/>
<Button Grid.Row="1" Content="{Binding EditarDispositivoCommand.DisplayName}" Command="{Binding EditarDispositivoCommand.Command}"></Button>
</Grid>
<ContentControl.RenderTransform>
<TranslateTransform X="{Binding X, Mode=TwoWay}" Y="{Binding Y, Mode=TwoWay}"></TranslateTransform>
</ContentControl.RenderTransform>
</ContentControl>
</DataTemplate>
I try to get that when a button in a itemTemplate is clicked the template of this item change to other template from resource.
Was that possible or i taking a bad way. Thanks a lot.
You could try using a DataTemplateSelector for Silverlight - it's not built in like WPF, but it can be achieved with some extra code.
Here is a good example from CodeProject:
http://www.codeproject.com/KB/silverlight/SLTemplateSelector.aspx
Just add an element to you view model to specify the template...
I just used the following article to do what you suggested.
I have two item templates defined for a view and can progamatically change the item template at runtime though codebehind
http://weblogs.asp.net/psheriff/archive/2010/08/25/change-templates-dynamically-in-silverlight.aspx
Hope this helps
(Sample also uses a button to change the item template)

Is there any way to programmatically change a Data/ItemTemplate in Silverlight?

I have a Listbox, which is using an ItemTemplate to display an image. I want to be able to change the size of the displayed image in the ItemTemplate. Through databinding I can change the Width, but the only way I can see how to do this is to add a Property (Say, ImageSize) to the class I am binding to and then change every item in the collection to have a new ImageSize. Is there no way to access the property of an item in that Datatemplate?
E.g.
<navigation:Page.Resources>
<DataTemplate x:Key="ListBoxItemTemplate">
<Viewbox Height="100" Width="100">
<Image Source="{Binding Image}"/>
</Viewbox>
</DataTemplate>
</navigation:Page.Resources>
<Grid>
<ListBox ItemTemplate="{StaticResource ListBoxItemTemplate}" ItemSource="{Binding Collection}"/>
</Grid>
Is there anyway to set the Width and Height of the viewbox without binding a property to every element in the collection?
You can use element binding to this. Try something like this:
<UserControl.Resources>
<DataTemplate x:Key="ListBoxItemTemplate">
<Viewbox Height="{Binding Value, ElementName=slider1}"
Width="{Binding Value, ElementName=slider1}">
<Image Source="{Binding Image}"/>
</Viewbox>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="205*" />
<RowDefinition Height="95*" />
</Grid.RowDefinitions>
<ListBox ItemTemplate="{StaticResource ListBoxItemTemplate}"
ItemSource="{Binding Collection}"/>
<Slider x:Name="slider1" Value="100" Maximum="250" Grid.Row="1"/>
</Grid>
If you know the sizes to which you'll be resizing, you could define a number of different ItemTemplates and switch bewteen them.

wpf border control to span the width of listboxItem

Im trying to define a dataTemplate for a business object in my wpf application a collection of which is being bound to a ListBox.
<UserControl.Resources>
<DataTemplate x:Key="ResizedItemsDataTemplate" DataType="{x:Type resizer:ResizeMonitorItem}">
<Border x:Name="bdr" BorderBrush="Blue"
BorderThickness="1"
CornerRadius="2"
Width="auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="14"></RowDefinition>
<RowDefinition Height="14"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding SaveAsFileName}"></TextBlock>
<TextBlock Grid.Row="1" Text="{Binding ResizedImageFilePath}"></TextBlock>
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0">
<Border BorderThickness="0,0,0,5" BorderBrush="DarkGray" >
<ListBox x:Name="ListBoxResizeItems" ItemsSource="{Binding Path=ResizeItems}" BorderThickness="0" ItemTemplate="{DynamicResource ResizedItemsDataTemplate}">
</ListBox>
</Border>
</Grid>
How can I get the border defined with x:Name=bdr to span the full width of each listbox item? At the moment it only spans the with of the textblocks inside it which dont neccessary fill the full width of the listboxitem and also vary for each listboxitem.
This is probably more to do with the ListBoxItems themselves not taking up the full width of the ListBox. Add the HorizontalContentAlignment="Stretch" attribute to your ListBox and see if it stretches the individual items to fill the width.
Worked it out. The trick is to set the HorizontalContentAlignment="Stretch" on your listbox to make its contents stretch the full width rather than fit the contents only.
<ListBox x:Name="ListBoxResizeItems"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Path=ResizeItems}"
BorderThickness="0"
ItemTemplate="{DynamicResource ResizedItemsDataTemplate}" >
</ListBox>
Sorry Matt, just got your answer thorugh as I was typing this post.
HorizontalContentAlignment is a nice, clean solution compared to what I was trying. Thanks!
Here's what ALMOST worked, but sometimes made a dialog box animated itself wider and wider forever:
Width="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"

Resources