I'm trying to create DataTemplates for a PropertyCollection (of PropertyDescriptors) to display the items in the collection in this format,
descriptor1 > descriptor2 > descriptor3 > descriptor4 > descriptor5
Each descriptor would be a link (using Hyperlink), my question is can I do this with Labels (which is not an ItemsControl host)? If yes, can anyone give me an example on how to achieve this with DataTemplates?
Also, is there anyway to access the property descriptor from the DataTemplate? For example suppose I want to use the current instance of property descriptor as the CommandParameter.
Appreciate any help, thanks.
you can try to do this with a ListBox with an ItemsPanel that uses a horizontal layout for the items (I'm just binding to a list of strings in my example). HTH.
Code:
public List<string> Properties { get; set; }
XAML:
<ListBox ItemsSource="{Binding Properties}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink NavigateUri="{Binding}">
<TextBlock Text="{Binding StringFormat={}{0} >}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Screenshot:
Related
I'd like to create a list in WPF that displays data in several columns, like Explorer display a list of files in 'Small icons' view mode:
Each item must be represented by a DataTemplate and the scrolling is supposed to be horizontal. How do I make such a list?
You need to change ItemsPanel of your ListBox to WrapPanel with vertical Orientation and disable vertical scroll bar on your ListBox
Something like this:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled" ItemsSource="{Binding=MyItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--my item template-->
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
try something like below.
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<DataTemplate>
<!--my item template-->
</DataTemplate>
</ListBox>
can use this link
try something like below.
<ListView ItemsSource="{Binding Files}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.View>
<GridView >
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Name}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
code behind sample.
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Files = new ObservableCollection<FileInfo>();
var files = new System.IO.DirectoryInfo("C:\\Windows\\").GetFiles();
foreach (var item in files)
{
Files.Add(item);
}
this.DataContext = this;
}
public ObservableCollection<FileInfo> Files { get; set; }
}
From a Database I am receiving a List with multiple Properties. One of those Properties is again a List of an Appendix Object containing ID Information and an Image.
I converted that List into an ObservableCollection and bound it to a WPF ListBox. Using a DataTemplate I show this content. Inside the DataTemplate I now have an ItemControl bound to the Inner-List (my Appendix with none, one or multiple entries):
<ListBox ItemsSource="{Binding Reports}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="Report Date:" FontWeight="Bold"/>
<Label Content="{Binding ReportDate.Date, StringFormat=dd.MM.yyyy , ConverterCulture=de-DE}"/>
<Label Content="Comment:" FontWeight="Bold"/>
<Label Content="{Binding Comment}"/>
</StackPanel>
//Here I would like to have a Button to add a Picture into the Appendix List
<ItemsControl x:Name="SelectedOnlyListBox" ItemsSource="{Binding Appendix}" Visibility="Collapsed">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Picture}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}, Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="SelectedOnlyListBox" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
My question is, how do I get the current Object via Binding into my Code. Because I will have multiple Buttons for one outer List (Reports) entry. But the Button should only add into the proper Inner List (Appendix).
Additional info: I am using the MVVM-Light Toolkit.
Thank you very much.
Edit: I forgot to mention that the first List is one of many Properties of a Detail class which again comes in a List of all Details. So with my DataContext already got a Property "SelectedDetail". This one I know...
But how do I now match the specific Button of each SelectedDetail.Report to my SelectedDetail.Reports.Appendix?
I have a WrapPanel that I'm filling in my ViewModel with UserControls:
<WrapPanel Width="250" Orientation="Horizontal" Margin="3">
<ItemsControl ItemsSource="{Binding PlaceableObjectsContent}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:PlaceableObjectViewModel}">
<local:PlaceableObjectUserControl>
<local:PlaceableObjectUserControl.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding DataContext.OnPlaceableObjectClicked, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
</local:PlaceableObjectUserControl.InputBindings>
</local:PlaceableObjectUserControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</WrapPanel>
When I fill them manuell with random Controls, everything works fine! I already read something about problems because of Using ItemTemplate!?
If its true, how can I manage that?
Thanks
You're putting a single ItemsControl inside a WrapPanel. That won't do anything. If you want your ItemsControl to use a WrapPanel to host its own items, here's how:
<ItemsControl
ItemsSource="{Binding PlaceableObjectsContent}"
Width="250"
Margin="3"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- etc. -->
Note that something has to constrain the width of the ItemsControl for this to work: Either it must be limited by the size of its parent, or a Grid Column, or even by setting the Width or MaxWidth properties of the ItemsControl element itself, either directly or via a Style.
I currently have a ListView which has has a datatemplate so that it displays all .jpg files in a given folder. Currently I have it set up as a wrap panel and I found that when the jpgs in this folder get large the program slows down. I'm guessing due to the loss of visualization. I have tried using This Example of a Visualizing WrapPanel - The reason this doesn't work for me is because I still get the obscure scroll-bar behavior, even though each item is the same height / width. I was just wondering if there was a better way to implement this. I wouldn't be bothered if I had to fix the amount of columns, e.g. a 3 x 3 displayed at one time.
My current listview looks like this:
<ListView ItemsSource="{Binding FilteredPhotoFiles}" SelectedItem="{Binding SelectedPhotoVM.SelectedPhoto}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="2,4,2,4">
<Grid.Background>
<SolidColorBrush Color="LightGray" Opacity="0.5"/>
</Grid.Background>
<Image Source="{Binding PhotoFileInfo.FullName}" Width="300" Height="170" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I was just wondering if there was a better way of doing this so that I do not lose perfomace, maybe some kind of GridView?
I'm adapting this solution to my needs: http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html
The XAML part of the listview is:
<ListView Grid.Row="1" Name="lvIcons" ItemsSource="{Binding}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
I've got a button to control if I want to show grouped or not and the code behind for this button is:
private void btnGroup_Click(object sender, RoutedEventArgs e)
{
this.Source.GroupDescriptions.Clear();
PropertyInfo pinfo = typeof(country_icon).GetProperty(cmbGroups.Text);
if (pinfo != null)
this.Source.GroupDescriptions.Add(new ropertyGroupDescription(pinfo.Name));
}
When grouping is on, the wrappanel is working nicely (i'm grouping by an integer property on the icons)
But when grouping is not on, no wrapping:
I'm not worried about different sizes of icon's - i'll fix that later.
How do I fix wrapping when not grouped ? Is there a different template in use ?
Thanks to the answer of this question WPF ListView with horizontal arrangement of items? to help get me to where I am now.