WPF - How to make ItemsControl single item content larger than ItemsControl itself - wpf

Is it possible to make a datatemplate for ItemsControl, which would 'enlarge' selected item's content beyond ItemsControl height, overlapping other ItemsControl items - but without altering ItemsControl height/width, without shifting adjacent ItemsControl items.
I have interaction triggers and bindings etc, just need UI elements capable of that.
Tried Popup element - but it doesn't look to be the best solution.
EDIT:
Thanks again for your replies, I tried to post a simplier description of my problem - and that was my mistake, sorry. Heres the EXACT problem:
(tried to apply ScaleTransform - it makes my ScrollViewer larger)
<s:SurfaceScrollViewer MaxWidth="1920" Margin="50" ClipToBounds="False"
VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="{Binding Path=ScrollViewerYearVisibility}">
<ItemsControl HorizontalAlignment="Center" BorderBrush="Red" BorderThickness="3"
ItemsSource="{Binding Path=YearItemsSource}"
ItemTemplate="{StaticResource DataTemplateYearItem}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</s:SurfaceScrollViewer>
<DataTemplate x:Key="DataTemplateYearItem">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False">
<Grid.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding Path=CommandDeviceDoubleClick}"/>
</Grid.InputBindings>
<Image VerticalAlignment="Center" HorizontalAlignment="Center"
Width="200" Height="200" Stretch="None"
Source="{Binding Path=ContentImagePathCurrent}">
</Image>
<Image VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False"
Margin="-248,-210,0,0"
Stretch="None"
Source="{Binding Path=SlideCurrent.ContentImagePath}">
<Image.RenderTransform>
<ScaleTransform ScaleX="3" ScaleY="3"/>
</Image.RenderTransform>
</Image>
</Grid>
</DataTemplate>

Related

WPF/XAML: Positioning primitives in nested data-structure within a canvas

in my current Project I have a nested data-structure. The root is an ObservableCollection ( terrainModel.terrainElements). Each of the elements in the collection host another ObservableCollection(drawElements) that consists of data to draw primitives in a canvas. Depending on the primitive I provide a DataTemplate so that it is rendered in the Canvas.
Here is the actual XAML:
<ItemsControl ItemsSource="{Binding terrainModel.terrainElements}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="1000" Height="500" Background="Aquamarine"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding drawElements}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type drawtype:LineElement}">
<Line Stroke="Black" X1="{Binding startPoint.X}" Y1="{Binding startPoint.Y}" X2="{Binding endPoint.X}" Y2="{Binding endPoint.Y}" />
</DataTemplate>
<DataTemplate DataType="{x:Type drawtype:CircleElement}">
<Ellipse Stroke="Black" Width="{Binding radius}" Height="{Binding radius}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type drawtype:RectangleElement}">
<Rectangle Stroke="Blue" Width="{Binding width}" Height="{Binding height}" Canvas.Left="{Binding position.X}" Canvas.Top="{Binding position.Y}"/>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The problem is however that I am not able to set the position of the primitives correct in the XAML, as Canvas.Left="{Binding position.X}" for example does not work as it is in the inner ItemsControl and not in the outer ItemsControl.
I also tried to transform the primitives like this:
<Rectangle.RenderTransform><TranslateTransform x:Name="myTransform2" X="{Binding position.X}" Y="{Binding position.Y}" /></Rectangle.RenderTransform>
This worked but ruined the position of following elements to draw. Of course I could draw everything in code of the view, but I would like to know if it's also possible to do in xaml.
The solution by Clemens worked:
Set a Canvas as the ItemsPanel for the inner ItemsControl the same way
you did for the outer one. Then use the RenderTransform solution, as
setting Canvas.Left and Canvas.Top would still not work because the
Rectangle will not become a direct child of the Canvas. You would need
to set an ItemsContainerStyle for the Left and Top bindings.
The outer Canvas should still (also) have a Canvas as its ItemsPanel.
Otherwise you will have problems with more than one terrainElement.
I thought that a new Canvas would be generated in the inner ItemsControl for every outer ItemsControl.
Here is the XAML if somebody is interested:
<ItemsControl ItemsSource="{Binding terrainModel.terrainElements}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding drawElements}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="1000" Height="500" Background="Aquamarine"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type drawtype:LineElement}">
<Line Stroke="Black" X1="{Binding startPoint.X}" Y1="{Binding startPoint.Y}" X2="{Binding endPoint.X}" Y2="{Binding endPoint.Y}" />
</DataTemplate>
<DataTemplate DataType="{x:Type drawtype:CircleElement}">
<Ellipse Stroke="Black" Width="{Binding radius}" Height="{Binding radius}">
<Ellipse.RenderTransform>
<TranslateTransform x:Name="myTransform" X="{Binding position.X}" Y="{Binding position.Y}" />
</Ellipse.RenderTransform>
</Ellipse>
</DataTemplate>
<DataTemplate DataType="{x:Type drawtype:RectangleElement}">
<Rectangle Stroke="Blue" Width="{Binding width}" Height="{Binding height}">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="myTransform2" X="{Binding position.X}" Y="{Binding position.Y}" />
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Wrap Panel with scroll viewer

I am using WrapPanel for dynamic content display line by line order like windows explorer windows, its working but when the horizontal and vertical ScrollBar enabled the WrapPanel display the contents are single line. Here we have contents less than 4 it shows perfect otherwise display single line.
Here is my xaml code
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0,10">
<ItemsControl ItemsSource="{Binding Designs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Left" Margin="200,11,0,0" TextWrapping="Wrap" Text="{Binding DsnName}" VerticalAlignment="Top" FontSize="16" FontFamily="Segoe UI Semibold" Foreground="#FF878787"/>
<Image Source="{Binding Image,FallbackValue={StaticResource Lost},TargetNullValue={StaticResource Lost},Mode=TwoWay}" Stretch="Fill" RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Left" Margin="10,10,0,10" Width="174"/>
<CheckBox HorizontalAlignment="Right" Margin="0,14,12,0" VerticalAlignment="Top" Width="16"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
How can fix this issue
Set height of WrapPanel or disable scrolling

WPF Control to emulate Outlook Attachment-View

I'm trying to get the ListView to look like the MS Outlook Attachment-Control. I've already got the horizontal scrolling, but it still displays only one item in a row.
How can I get it to look like this?
What I've achieved so far:
<Grid x:Name="grdAttachments"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MaxHeight="45" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65" />
<ColumnDefinition Width="15" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Margin="3,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Cursor="Hand"
Text="Angefügt:" />
<ScrollViewer Grid.Row="0" Grid.Column="2">
<ListBox x:Name="libAttachments"
Background="Transparent"
ItemsSource="{Binding Attachments}"
MouseDoubleClick="lvAttachments_MouseDoubleClick">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,10,0" Orientation="Horizontal">
<Image Source="{Binding MimeTypeIcon}" Stretch="None" />
<TextBlock Margin="5,0,0,0" Text="{Binding File.Name}" />
<StackPanel.ContextMenu>
<ContextMenu>
<ContextMenu.Items>
<MenuItem Click="btnOpenAttachment_Click" Header="Öffnen">
<MenuItem.Icon>
<Image Source="/Images/magnifier.png" Stretch="None" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Click="btnSaveAttachment_Click" Header="Speichern unter">
<MenuItem.Icon>
<Image Source="/Images/disk-black.png" Stretch="None" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu.Items>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
It sounds like what you want is an ListBox with a custom ItemsPanel.
<ListBox>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
The snippet above configures a ListBox to use a WrapPanel as the layout provider or "ItemsPanel" for the items it is to present. From there it may make sense to implement a custom Item Container style, and/or custom Data Templates. You could easily apply a DataTemplate as you did above if you are using an MVVM pattern and data binding to a collection (preferably observable)
<DataTemplate>
<StackPanel Margin="0,0,10,0" Orientation="Horizontal">
<Image Source="{Binding MimeTypeIcon}" Stretch="None" />
<TextBlock Margin="5,0,0,0" Text="{Binding File.Name}" />
</StackPanel>
</DataTemplate>
To complete this picture, a scroll viewer can be used so long as it's height is constrained by either a parent layout control (Grid.Row = 1 where RowDefinition Height="constant") or my an explicit height being set on the ScrollViewer.
My final solution based on yours looks like this:
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<ListBox
ItemsSource="{Binding Attachments}"
MouseDoubleClick="lvAttachments_MouseDoubleClick"
SelectionMode="Single">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,10,0" Orientation="Horizontal">
<Image Source="{Binding MimeTypeIcon}" Stretch="None" />
<TextBlock Margin="5,0,0,0" Text="{Binding File.Name}" />
<StackPanel.ContextMenu>
<ContextMenu>
<ContextMenu.Items>
<MenuItem Click="btnOpenAttachment_Click" Header="Öffnen">
<MenuItem.Icon>
<Image Source="/Images/magnifier.png" Stretch="None" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Click="btnSaveAttachment_Click" Header="Speichern unter">
<MenuItem.Icon>
<Image Source="/Images/disk-black.png" Stretch="None" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu.Items>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
A few things to note: When possible, consider using Commands instead of events, they can lead to looser coupling. Introducing a Behavior might even make sense if the behavior it's self is something that you might have other places in your project or re-usability is ideal.
Ok so where it seems you got snagged up was with your ListBox still pushing things in single column fashion and the lack of ability to give you something to fire off say a click event. So what I had in mind was something more like this;
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Height="300" HorizontalContentAlignment="Stretch">
<ItemsControl ItemsSource="{Binding Collection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,0" Orientation="Horizontal">
<Image Source="{Binding MimeTypeIcon}" Stretch="None" />
<HyperlinkButton Margin="5,0,0,0" Text="{Binding File.Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
I wasn't to sure what you were trying to do with your magnifier and disk though I see your Clicks for them, but you can add those to this layout however you like, just a note though, I just free-handed this between meetings so never built it but should work fine. If not we'll plug at it again. Main differences are changing to a hyperlinkbutton to give you click and some other subtle differences from Firoso's but his is still technically sound, or should be anyway :)

Shrinking effect of Tiles on ListBox on Windows Phone

I've created a listbox like this
<ListBox Name="lstNews" SelectionChanged="lstNews_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,12,12" Width="180" Height="180">
<Grid.Background>
<ImageBrush>
<ImageBrush.ImageSource>
<BitmapImage CreateOptions="BackgroundCreation" UriSource="{Binding Picture}" />
</ImageBrush.ImageSource>
</ImageBrush>
</Grid.Background>
<StackPanel Background="#AA000000" VerticalAlignment="Bottom" Height="70" >
<TextBlock Foreground="White" TextWrapping="Wrap" VerticalAlignment="Bottom" FontSize="16" Text="{Binding Title}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I need to add a shrinking effect when the user taps on an item. I've seen a lot of apps do that, I dunno how.
I assume you are talking about the tilt effect, which can be found in the wp7 toolkit.
You can set it at the global level by doing this,
<phone:PhoneApplicationPage xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
toolkit:TiltEffect.IsTiltEnabled="True">
Some good tutorials.

Tab order and index in WPF using the MVVM pattern

I'm having an issue with tabbing through the controls on a WPF application using the MVVM pattern. I have the following XAML which defines a tree structure
<Grid Background="Transparent" Margin="10">
<TreeView ItemsSource="{Binding FirstLevelNavigableViewModels}" Background="Transparent"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0"
ItemContainerStyle="{StaticResource TreeViewItemStyle1}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type ViewModel:VendorViewModel}" ItemsSource="{Binding Children}">
<View:VendorView HorizontalContentAlignment="Stretch" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type ViewModel:ProductViewModel}">
<View:ProductView HorizontalContentAlignment="Stretch" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
When the treeview is loaded, the XAML for the "ProductView" is as follows
<Border Margin="0,2,2,2" CornerRadius="3" Background="#3FC7B299" DockPanel.Dock="Right" HorizontalAlignment="Right" Width="109">
<StackPanel Orientation="Vertical" Margin="6,4">
<DockPanel>
<TextBlock DockPanel.Dock="Left" FontFamily="Segoe" FontSize="10" FontWeight="Medium"
Foreground="Black" Opacity="0.75"
Text="CALC. REG. PRICE"></TextBlock>
<Button Width="10" Height="10" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Padding="-4" Margin="0" Command="{Binding UserDefinedRetailPriceCommand}" Visibility="{Binding UserDefinedRetailPriceButtonView}">
<Image Width="10" Height="10" Source="/Arhaus.Pricing.Client;component/Styles/Images/error.png"></Image>
</Button>
</DockPanel>
<TextBox FontFamily="Segoe" FontSize="16" FontWeight="Medium" KeyboardNavigation.IsTabStop="True" KeyboardNavigation.TabIndex="{Binding RegularPriceTabIndex}"
Foreground="Black" Opacity="0.9" KeyboardNavigation.TabNavigation="Continue"
ebf:LostFocusBehaviour.LostFocusCommand = "{Binding LostFocusSugg}"
Text="{Binding NewSuggestedRetailPrice,Converter={StaticResource FormattingConverter}, ConverterParameter=' \{0:C\}', Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Background="#FFE6DED3" BorderBrush="#FFE6DED3" DataContext="{Binding StringFormat=\{0:c\}, NotifyOnValidationError=True}" Padding="0" TabIndex="1"></TextBox>
</StackPanel>
</Border>
I have the Tab Index bound to an integer that is ever increasing and bound as the treeview is loaded (I.E. I have it setup as tab index 1, 2, 3 etc. as each successive model is loaded).
I would like to be able to hit tab and jump to the next textbox in the treeview but when I click the TAB key, nothing happens. I'm not sure if I have the tabbing setup correctly but I'm very new to WPF and at a loss as to where and how to set the tabbing to make it work. I'm used to WinForms where you just set the tab index and go from there.
Thank you for your assistance, I apologize for the large code block.
I don't have a solution ready but some thoughts that maybe may help:
I don't know what RegularPriceTabIndex returns but probably it begins for each new TreeViewItem at the same index?
The same tab-index is given then multiple times because of repeating use of ProductView. Perhaps this leads to a problem. You can try setting FocusManager.IsFocusScope="true" for the ProductView. Maybe this helps.
Try also to set Control.IsTabStop="true" on the TextBox.

Resources