WPF Control to emulate Outlook Attachment-View - wpf

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 :)

Related

Nested ItemsControl Orientation

I have a nested ItemsControl. My data structure is an ObservableCollection of Campaigns which consist of a Campaign class and an observableCollection of Data counts (total, assigned, unassigned, closed). What I need is the following:
CAMPAIGN.NAME
TOTAL UNASSIGNED ASSIGNED CLOSED
CAMPAIGN.NAME
TOTAL UNASSIGNED ASSIGNED CLOSED
I am able to get the first part of this, but for some reason it will not honor the orientation for the second ItemsControl. What am I missing? My XAML is:
<ItemsControl x:Name="icCampaignChicklets" ItemsSource="{Binding CampChicks}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="gridContent">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="CampaignHeader" Height="20" Text="{Binding Path=Campaign.Name}" Grid.Row="1" VerticalAlignment="Top" TextWrapping="Wrap" HorizontalAlignment="Left" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10">
<ItemsControl x:Name="icChicklets" ItemsSource="{Binding Path=Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="140" Background="{Binding Background}" Cursor="Hand"
MouseLeftButtonDown="Chicklet_MouseLeftButtonDown"
>
<Grid x:Name="gridContent" Margin="8,4">
<TextBlock Text="{Binding Caption}" Foreground="White" FontSize="17" />
<TextBlock Text="{Binding CountCaption, Mode=OneWay}" Foreground="White" FontSize="45" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="7" />
<TextBlock Text="Ú" Foreground="#99ffffff" FontSize="30" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="3,5" FontFamily="Wingdings 3" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If you want to change the orientation of the contents of an ItemsControl, set its ItemsPanel property like so:
<ItemsControl
...attributes...
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Wrapping it in a horizontally-oriented parent StackPanel will merely arrange it and its siblings horizontally, but in this particular case it has no siblings.

Why my stackpanel items always aligning to vertical if even i mentioned horizantalmode in silverlight?

I wrote the below code in my page:
<StackPanel HorizontalAlignment="Left" Height="166" Margin="10,602,0,0" VerticalAlignment="Top" Width="1346" x:Name="thumbnailViewer">
<ScrollViewer
x:Name="thumbnailViewerScroller"
Padding="0"
BorderThickness="0"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden">
<StackPanel Orientation="Horizontal" >
<ItemsControl x:Name="UserList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--<StackPanel Orientation="Horizontal">-->
<Image Source="{Binding imageurl}" Tag="{Binding Path=id}" Width="164" Height="150" Margin="4" Stretch="Fill"></Image>
<!--</StackPanel>-->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</StackPanel>
Inside of the scrollviewer i mentionsed stackpanel and aligning the items as horizontal.But always i am getting the items alignment as vertical while running of the code.Please tell me how to align the items as horizontal?What was wrong in my code why items are aliging to vertical even i mentionsed Orientation="Horizontal in stackpanel.
EDIT:
<ScrollViewer
x:Name="thumbnailViewerScroller"
Padding="0"
BorderThickness="0"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden">
<!--<StackPanel Orientation="Horizontal" >-->
<ItemsControl x:Name="UserList">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!--<DataTemplate>-->
<StackPanel Orientation="Horizontal">
<Image Source="{Binding imageurl}" Tag="{Binding Path=id}" Width="164" Height="150" Margin="4" Stretch="Fill"></Image>
</StackPanel>
<!--</DataTemplate>-->
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Scrollviewer>
</Stackpanel>
Use the ItemsPanel of the ItemsControl instead.
<ScrollViewer>
<ItemsControl ...>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding imageurl}"
Tag="{Binding Path=id}" Width="164" Height="150"
Margin="4" Stretch="Fill"></Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

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.

Order Images in ListBox DataTemplate Horizontally

Preview
alt text http://img39.imageshack.us/img39/5466/howtoorderhorizontal.jpg
On the highlighted item, the images still ordered vertically even I already use <StackPanel Orientation="Horizontal">. Am I missing something?
I don't want the images have ListBoxItem behavior (hover/click). I had added IsEnabled="False" to the list box, but the images' opacity decreased : ( Do you have any idea how to do this thing?
Data template
<!-- FacilityTreeView data template -->
<telerik:HierarchicalDataTemplate x:Key="FecilityTemplate" ItemsSource="{Binding Facilities}">
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding Icons}" BorderThickness="0" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Source}" Margin=" 0,0,2,0" ToolTipService.ToolTip="{Binding Tooltip}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="{Binding Description}" VerticalAlignment="Center" />
</StackPanel>
</telerik:HierarchicalDataTemplate>
By using ItemsPanelTemplate.
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Source}" Margin=" 0,0,2,0" ToolTipService.ToolTip="{Binding Tooltip}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ListBox.ItemsPanelTemplate>
You need to use <StackPanel Orientation="Horizontal"> as an ItemsPanelTemplate.
Read more here.
I was trying the solution and I found it's incomplete, ItemsPanelTemplate must be inside <ListBox.ItemsPanel>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

How do I make WPF ListView items repeat horizontally AND vertically?

I have a ListView where I would like to display things horizontally. That works fine, but now I would need to have them display like in a Windows Explorer type.
For example :
A B C
D E F
G H I
or
A B
C D
E F
G H
I
Is it possible in a ListView?
If you want your items to all have the same size, I would go for a UniformGrid. It one of those overlooked controls, might be very useful in this situation.
This is how I made a quick-and-dirty toolbar:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding}"
ToolTip="{Binding Tooltip}">
<StackPanel Orientation="Vertical">
<Image Height="16"
Width="16"
RenderOptions.BitmapScalingMode="NearestNeighbor"
Source="{Binding Image}"
HorizontalAlignment="Center" />
</StackPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Sounds like you're looking for WrapPanel. I don't think it works for ListView, but if you want a generic items container to use WrapPanel as it's layout, you can do this with ItemsControl and fill it with whatever elements you want. Something like the following:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
<TextBlock Margin="20" Padding="20" Text="Blah" Background="#999" />
</ItemsControl.Items>
</ItemsControl>

Resources