WPF ItemsControl with one stack of items - wpf

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.

Related

Clipping the content of Canvas inside DataTemplate

I have a line inside Canvas as a root element on WPF window that looks fine. If I put it into the DataTemplate of ItemsControl then line will be looking clipped by StackPanel as a ItemsPanelTemplate. I've checked that other panels such as Grid as a ItemsPanelTemplate doesn't clip the content. I know that Canvas will not clip the content anyway. This appears in runtime only, not a design time. What is the root of problem?
<ItemsControl ItemsSource="{Binding ...}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel ClipToBounds="False"
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas Width="100"
Height="100"
ClipToBounds="False">
<Line X1="0"
Y1="0"
X2="-10"
Y2="10"
Stroke="DeepPink"
StrokeThickness="10" />
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

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

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.

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>

What XAML control should I use to keep all child elements within its borders in WPF?

I'm having a UI design issue, this is what I want the contents of my app window to shrink to fit the smallest dimension of the window.
Using the XAML below, when the window is too narrow the contents are shrunk to fit. Perfect. My problem is when the window is too short, the contents fall out the bottom, like this:
<ItemsControl ItemsSource="{Binding GroupStatsDisplayList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="Red" Margin="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Viewbox Margin="4" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="Auto" Height="Auto" >
<ListBox>
<StackPanel Orientation="Horizontal" Margin="5" Background="Blue">
<Label Content="{Binding GroupID}" FontWeight="Bold"/>
<Label Content="{Binding GroupName}" Width="100" FontWeight="Bold" />
<Label Content="{Binding CallsInQueue}" FontWeight="Bold" />
<Label Content="{Binding TSF}" FontWeight="Bold" />
</StackPanel>
</ListBox>
</Viewbox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have read in answers to similar questions that the ItemsControl uses a StackPanel as its default itemspanel and that the StackPanel does behave the way I'm seeing. A grid has been recommended to overcome issues like mine.
So I tried telling my ItemsControl to use a Grid:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Background="Red" Margin="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Better because the contents do resize when constrained in either direction. Worse because it seems like there is only one ViewBox->ListBox element that gets updated with the last item in my collection (I can see the three items in the collection cycle through the display as the app starts up). I don't see all items in my collection on screen, only the last one.
I also read that a DockPanel could save me...
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel Background="Red" Margin="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
That's when things got crazy and I decided to write this question. Now all items in my collection are there, but they appear one by one when I expand the window horizontally, each new item appears as the existing ones expand to the vertical extent of the window.
How do I get a layout that looks like the first image but will shrink to fit within the smallest dimension of the window?
Why do you have a ListBox in your DataTemplate, when you have only one hardcoded item the StackPanel? To clarify that: The ItemTemplate defines how you want one item to appear in your items Collection. For Example you could create an ItemTemplate which shows an Album Cover on the left, the Artist Name next to it and on the bottom a Star Rating.
A Grid should not be used as an ItemsPanel, because for that you would need to supply a dynamic Grid/Col Definitions collection.
Using a ViewBox is my best advice. But not in the ItemTemplate, this would only size one children, a viewbox around the whole itemscontrol.
This is the XAML that I used based on the answer from dowhilefor.
<Viewbox Margin="3" >
<ItemsControl ItemsSource="{Binding GroupStatsDisplayList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="1" Background="LightGreen">
<Label Content="{Binding GroupID}" FontWeight="Bold"/>
<Label Content="{Binding GroupName}" Width="100" FontWeight="Bold" />
<Label Content="{Binding CallsInQueue}" FontWeight="Bold" />
<Label Content="{Binding TSF}" FontWeight="Bold" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Viewbox>
I haven't done WPF in a while, and probably it's not considered very good practice, but maybe you could just use a scaletransform on your entire gui ?
I always liked playing around with them.

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)

Resources