Is there a general mechanism in WPF that allows for any or almost any control to be selected? For instance, you could have some Image controls on a WrapPanel defined in XAML, and you need to be able to select them either one by one, or by dragging over with the mouse to mark multiple.
In terms of code, I can imagine the following:
<WrapPanel>
<Image Source="{StaticResource ResourceKey=pic1}" />
<Image Source="{StaticResource ResourceKey=pic2}" />
<Image Source="{StaticResource ResourceKey=pic3}" />
<Image Source="{StaticResource ResourceKey=pic4}" />
<Image Source="{StaticResource ResourceKey=pic5}" />
</WrapPanel>
Yes, its called a ListView.
If you need the look of a WrapPanel, just set the ItemsPanel property like so:
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Documentation on MSDN.
You would need to make the Image objects part of the ItemTemplate in your example. You can manually define the Items collection or use a CompositeCollection as the items source as well.
For me it worked with the solution I found here: WrapPanel doesn't wrap in WPF ListView
It's basically the same solution as BradleyDotNET's, but it includes ScrollViewer.HorizontalScrollBarVisibility="Disabled" in the list view and by doing so, it makes the wrap function work without needing to do anything more.
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>
Related
I'm looking for the exact solution used by the stock Photo app in Windows 10 to display a list of photos where the dimensions are different. Basically the height of the row are fixed but the width of each element is variable, determined by its relative dimension. A solution I used before was to use WrapPanel as the ItemsPanelTemplate. But using that means I lose the UI virtualisation for a very long list. There is certainly a solution used by Microsoft for the Photo app but I can't find it anywhere.
You can use WrapPanel from XAML Toolkit in your UWP application.
Or you can try to do it this way:
<GridView ItemsSource="{Binding}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="100">
<Image Width="100" Height="50" Source="{Binding somesource}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="8" Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Or you can also use VariableSizedWrapGrid (it will let you to have images with different height)
I have a question regarding nested collections usage in UWP apps with XAML/C#.
Let's say I have a list of items with multiple images in each.
I need to show a scrollable list with all of the images inside the item data.
So far I can see a solution to create GridView with ItemsTemplate that has ItemsControl inside it. But it seams very slow and not optimized solution.
Is there any better suggestion to solve that?
Without much context, I can only think of following :
You have a large amount of data to be displayed, but not all at once. In this case you should consider using controls that support virtualization.
Flattening the data source before binding it. This may improve the performance by a little.
Update
Here is how you can do it :
<ListViewItem ItemsSource="{Binding Posts}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Message}" />
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Photos}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListViewItem>
In my wp8 app I show some content (images for example). I use LongListSelector, and in each LLS's item have ItemsControl with collection of images. I want to show two images in one line, so I use a wrappanel. But it throws XamlParseException in line InitializeComponent() in usercontrol's page. Without wrappanel all works fine. Here the code
<ItemsControl HorizontalAlignment="Center" ItemsSource="{Binding Vkontakte.Attachments.Photos}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Height="100" Width="100" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Margin="0,10,0,0" >
<Image.Source>
<BitmapImage UriSource="{Binding Src}" CreateOptions="BackgroundCreation" />
</Image.Source>
</Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Maybe problem is in the case, that ItemsControl is in the StackPanel?
The exception my be thrown due to your ItemsSource binding. If Vkontakte is not an object on your datacontext then you may need to take a look at what you are binding to. It needs to be a collection of some kind of object.
I am trying to do an interface in WPF where a list of item is displayed, taking as little vertical space as possible:
My instinct was to use an ItemsControl to bind my list, and to put the UI for each item into a WrapPanel. Unfortunately by default, each item starts at a new line regardless of the window's size. Adding a StackPanel with Orientation="Horizontal" makes all items in a single line, regardless of the size...
<!--<ScrollViewer Grid.Row="0" Grid.Column="0"
VerticalScrollBarVisibility="Auto">-->
<ItemsControl Margin="0,4" ItemsSource="{Binding Path=Watchers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type Core:Watcher}">
<WrapPanel Orientation="Horizontal">
<TextBlock Margin="0,2" Text="{Binding Path=Name}"
Width="250px" />
<TextBox Text="{Binding Path=Value, Mode=OneWay}"
Width="300px">
</TextBox>
</WrapPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
<!--</ScrollViewer>-->
Any pointers?
Bonus point: Where should I add a ScrollViewer in order to have the behavior shown in my mockup?
Thanks a lot!
The WrapPanel has, as well as the StackPanel, an Orientation property, which defaults to Vertical. So your list should wrap (assuming you have enough space at hand) if your ItemsPanelTemplate looks like this:
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
About the ScrollViewer:
The desired behavior should be achieved by defining it like follows (not tested though, and I omitted all for this example unnecessary stuff):
<ScrollViewer HorizontalAlignment="Stretch">
<ItemsControl MinWidth="550" Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}}" />
</ScrollViewer>
I think you want the WrapPanel in the ItemsPanel and the StackPanel in the ItemTemplate.
why not use the WrapPanel as ItemsPanelTemplate?
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
as long as the items have space to the left they would be arranged horizontal.
Im a beginner in WPF programming, coming from .NET 2.0 C#.
Im trying to make a horizontal StackPanel which should be filled with data from a table in a database. The problem is that I want it to display an image with some text from the table below and then stack those two items horizontally.
Here's some pseudo-code to display what I want to do:
<StackPanel Orientation="horizontal" ItemsSource="{Binding Path=myTable}">
<StackPanel>
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}"></Label>
</StackPanel>
</StackPanel>
I simply cannot figure oout how to do this.
Julien's answer is correct for your written description, however, looking at your XAML, it appears you are looking for something like the following:
<DataTemplate x:Key="UserDataTemplate">
<StackPanel>
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}" />
</StackPanel>
</DataTemplate>
<ItemsControl x:Name="UserList" ItemTemplate="{StaticResource UserDataTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
You definately need an ItemsControl (or some derivation of) to bind your source to. Then you can change the the orientation by setting it's items panel (which I believe is a VirtualizingStackPanel with Vertical orientation by default) so just set it to a VirtualizingStackPanel with Horizontal Orientation. Then you can set the ItemsTemplate for each of your items to the layout you desire (an image stacked on top of text bound from your database).
Basically, you want to use a control capable of displaying an enumeration of objects. The control capable of this is the class ItemsControl and all of its descendants (Selector, ListBox, ListView, etc).
Bind the ItemsSource property of this control to a list of objects you want, here a list of users you've fetched from the database. Set the ItemTemplate of the control to a DataTemplate that will be used to display each item in the list.
Sample code:
In a Resources section (for example Window.Resources):
<DataTemplate x:Key="UserDataTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}" />
</StackPanel>
</DataTemplate>
In your Window/Page/UserControl:
<ItemsControl x:Name="UserList" ItemTemplate="{StaticResource UserDataTemplate}" />
In your code behind:
UserList.ItemsSource = ... // here, an enumeration of your Users, fetched from your db