I have this pretty simple window with a Grid containing two columns, a TextBlock and a TextBox.
What I need it to set the column 0 to automatically size to its content and to have column 1 (content) to be 4 times the size of the column 0.
How can I do that. I will create a Grid descendant if this is the solution because I really need this feature.
Edit: more explanations. The content of the column 0 won't change at runtime so the size of the column 0 or column 1 must not change on runtime. The grid will be the child of a window configured with SizeToContent="WidthAndHeight" so no extra space must exist.
Answer to Dmitry: I tried what you say with the following code and it is not working at all:
<Window x:Class="UnderstandSizing.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
SizeToContent="WidthAndHeight" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" />
<ColumnDefinition Width=".75*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="THIS IS THE LABEL:" />
<TextBox Grid.Column="1" Text="content" />
</Grid>
</Window>
Last Edit: Why the hell do I (or anyone) need this?
One of the nice things of WPF is its hability to work without fixed sizes right? If you are impaired and you have a bigger font size everything will look fine. If you translate your UI to another language that needs x2 size everything will look fine. If you have different PPI settings everything will look fine.
But what I don't want to see is screens changing its size at runtime because users are not used to this. That's why I want to set the size of the entry fields to a multiple of a know field. If I let the label cell to re size to what it needs and then I set the content cell to a multiplier of the label I will get the benefits of autosizing with the behaviour that users expect of having fixed size screens (unless they change it resizing it).
You can use bindings on grid columns:
<Grid.ColumnDefinitions>
<ColmunDefinition Width="Auto" x:Name="firstCol"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=firstCol, Converter={StaticResource MultiplyConverter}, ConverterParameter=4}" />
</Grid.ColumnDefinitions>
Then the converter:
public class MultiplyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double originalValue;
double multiplier;
if (value != null && parameter != null &&
double.TryParse(value.ToString(), out originalValue) &&
double.TryParse(parameter.ToString(), out multiplier)) //Can be lots of things: sentinel object, NaN (not a number)...
{
return originalValue * multiplier;
}
else return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
You could write an attached property for grid columns also.
Edit:
If the sizes are known at compile time, wouldn't it be easier to set the widths manually?
You could use a BindingConverter for that, I'd go with separate items in a horizontal StackPanel (look that the StackPanel's width is big enough for your contents):
Here's the cleaned code.
MainWindow.xaml:
<!-- define xmlns:local="clr-namespace:YourAppNamespace" -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<StackPanel.Resources>
<local:WidthConverter x:Key="wc" />
</StackPanel.Resources>
<Grid Background="Gray" x:Name="col1">
<TextBlock Text="blub"/>
</Grid>
<Grid Background="Orange" Width="{Binding ElementName=col1, Path=ActualWidth, Converter={StaticResource ResourceKey=wc}}">
<Label Content="bla"></Label>
</Grid>
</StackPanel>
MainWindow.xaml.cs:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is double))
{
return Binding.DoNothing;
}
return ((double)value) * 4.0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Taken from: http://www.tanguay.info/web/index.php?pg=codeExamples&id=36
the idea is to use:
Update 2 - full XAML posted (mind the behavior of your grid's children):
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" />
<ColumnDefinition Width=".75*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Background="Yellow" Grid.Column="0">
<TextBlock Text="THIS IS THE LABEL:" />
</Grid>
<Grid Background="Blue" Grid.Column="1">
<TextBox Background="Transparent" Text="content" />
</Grid>
</Grid>
</Grid>
</Window>
I've just checked it and it worked.
Update: Simply put - there's no out of the box way for doing this in WPF. Depending on your circumstanes you'll have to come up with some sort of a trick to get your grid working.
Another problem is - in general WPF layouts are designed to be protective, i.e. if your grid's child cannot be shrinked down - normally your layout logic should accomodate for it, typically by suspending some layout rules.
As I understand you are trying to layout the label (textblock) and the corresponding entry field for it. As an indicator, you should first see the Beth Massi's Windows Client video on simple data entry form which is on developing a data entry form but laying out is also demonstrated very well.
Particularly observe how she lays out the controls on the WPF Window using the designer, properties window and XAML, and then I think you should not have a need for the first column to be of Auto size and second column of 4* first column.
EDIT: As per update in question, I am posting a possible solution as below:
XAML file code (Notice the SizeToContent usage in Window and that the binding is to ActualWidth property for Textbox control):
<Window x:Class="GridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:GridTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
d:DesignHeight="350"
d:DesignWidth="525"
SizeToContent="WidthAndHeight"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<local:FourWidthConverter x:Key="FourWidthConv" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="tb"
Grid.Column="0"
Text="Auto Text, change at design time to see changes in Width" />
<TextBox Name="tx"
Grid.Column="1"
Width="{Binding ElementName=tb,
Path=ActualWidth,
Converter={StaticResource FourWidthConv}}"
Text="4 * col 1 width displaying Text in SizetoContentWindow" />
</Grid>
</Window>
.Xaml.cs file code (Notice the converter here):
using System.Windows;
using System.Windows.Data;
namespace GridTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class FourWidthConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return 4 * (double)value;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}
Related
I have a set of buttons I am trying to make the same width, rather than the default width. However, the maximum width they should be is to make the button with the longest text display nicely.
First, I tried using a Grid and using columns with a * width, but that filled the entire window. It was suggested that I use a UniformGrid, but that had the same result. I cannot just set the width because the value in the button can change at any time by the user setting which language the button should display in.
I eventually set up a MultiBinding and got things to almost work, with the button resizing up when the locale is changed. My problem now is that it does not resize back down.
Here is my XAML content; I hard-coded the text in so this should be copy/pasteable as-is:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="0,10,0,0">
<Button Name="DeleteBranchOkButton"
Content="Ok"
HorizontalAlignment="Left"
Padding="5">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="DeleteBranchCancelButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
<Button Name="DeleteBranchCancelButton"
Content="Cancel"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Padding="5">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="DeleteBranchOkButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
</StackPanel>
My converter implementation is:
public class EqualWidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Math.Abs(values.Cast<double>().Max()) < .1 ? -1 : values.Cast<double>().Max();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] {};
}
}
The problem now is allowing the buttons to resize back down if the language is changed and the buttons are wider than necessary. One potential solution I identified is injecting the settings control into each view, handling the languageChanged event, and setting the MinWidth property to 0 in the code behind.
I would rather not do that, however, unless it is the only method possible; I would much rather have each control not need to know about the settings implementation. Is there a better way to do this, perhaps without even needing the converter?
This is what using a Grid results in:
This is what I want:
Grid.IsSharedSizeScope and SharedSizeGroup to the rescue! These two properties let you specify grid columns/rows to share the same width/height, even across multiple grids.
Solution without wrapping
<Grid Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">New Branch</Button>
<Button Grid.Column="1">Merge</Button>
<Button Grid.Column="2">Delete Branch in French!</Button>
</Grid>
Solution with wrapping
<WrapPanel Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>New Branch</Button>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>Merge</Button>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>Delete Branch in French!</Button>
</Grid>
</WrapPanel>
There are several possible solutions to your problem. The most trivial and straightforward would be using Buttons of equal size placed either within the layout Grid control with three equally-sized columns (use *) and Buttons' properties set to default Stretch mode, or place them into StackPanel (as per your sample); then encapsulate the Button's TexBlock into:
<Viewbox>
<TextBlock Text="YourText" Style="{Optional}"/>
</Viewbox>
in order to resize/fit the content nicely.
Okay, What I'm trying to accomplish:
A tabheader which gets an image if the textbox inside has text. but if the textbox inside the TabItem doesn't have any text, then the image should not be shown.
this is what I have so far:
----- TAB ITEM CODE -----
<TabItem Name="tabAantekeningen" Header="">
<TabItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="8" Text="Aantekeningen"/>
<Image Grid.Column="1" Source="..\Resources\validate.png" Height="20" Width="17"/>
</Grid>
</DataTemplate>
</TabItem.HeaderTemplate>
<TextBox Name="txtOmschrijving" TextWrapping="Wrap" AcceptsReturn="True"></TextBox>
</TabItem>
----- TAB ITEM CODE -----
----- Code Behind -----
public void SetTabItemHeader()
{
if (String.IsNullOrEmpty(txtOmschrijving.Text))
{
tabAantekeningen.Header = "Aantekeningen";
}
}
----- Code Behind -----
IS there a way that I can say: txtOmschrijving.Text == Empty so hide the Image?
Edit: Didn't see your seccond question there, yes there is use a IValueConverter, where you check if the string is empty and Bind To Visibility for instance, so you return Visbility.Collapsed when empty or else Visbility.Visible.
Like this :
public class StringEmptyToVisbililityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value == null) || !(value is string) || string.IsNullOrEmpty(value.ToString()) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Fully working xaml, change your namespaces and URI pack
<Window x:Class="TabItemHeader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TabItemHeader"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:StringEmptyToVisbililityConverter x:Key="StringEmptyToVisbililityConverter"/>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Name="tabAantekeningen">
<TabItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="8" Text="{Binding Path='Header',RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
<Image Grid.Column="1" Source="pack://application:,,,/TabItemHeader;component/Resources/Images/validate.png" Height="20" Width="17" Visibility="{Binding Path='Header', Converter={StaticResource StringEmptyToVisbililityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
</Grid>
</DataTemplate>
</TabItem.HeaderTemplate>
<TextBox Name="txtOmschrijving" TextWrapping="Wrap" AcceptsReturn="True"></TextBox>
</TabItem>
</TabControl>
</Grid>
This will bind to the listboxitem which wraps everything in a listbox. The converter will only show this image when the string is not empty. You can do alot of fun with them :)
WPF cheat sheet is a really handy and compact paper on all types of bindings.
Oh..I am assuming this image will be deployed with your application? Then please ensure that your image is set to resource, you should consider using uri packs as well for your images, an example is in this post as well as the xaml provided. If your image is dynamic, you will have to bind them to some model in an observablecollection.
Tip: I'll stop pushing this to far, but you should consider having a look at the MVVM pattern. I just used code behind my self, so the answer wouldn't get to big. It's whole other topic! =) There are also cleaner ways to either share templates, and change them on types bound in the collection.
Hope it helps.
Cheers,
Stian
I have a window split up by grids (left center right), where the center control I want to have multiple controls that will need to fill their heights as tall as possible while splitting it evenly amongst the other controls.
One way I was able to achieve this is through a grid like so:
<!-- Center -->
<Grid Grid.Row="0" Grid.Column="2" Height="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WebBrowser Grid.Row="0" Name="browsc" />
<WebBrowser Grid.Row="1" Name="browsa" />
<WebBrowser Grid.Row="2" Name="browsb" />
</Grid>
This works, however I need to add and remove rows dynamically, where it's possible a row in the middle will need to be removed (causing the need to reorder the rows each control rests on which I can't imagine a simple solution for).
If there isn't a better way to split the controls than this, how would I add and remove rows via code (C#)?
If there's a better way to do it, how can I do this where all I have to worry about are adding and removing the controls themselves and not mess with row properties?
Thanks!
This is an example on how to add new RowDefinition to Grid programmatically and set control to a specific Grid Row :
//following line equal to XAML : <RowDefinition Height="*" />
var newrow = new RowDefinition {Height = new GridLength(1, GridUnitType.Star)};
//add new rowdefinition to grid
myGridName.RowDefinitions.Add(newrow);
//set webbrowser control to newly added row, or any row number you wish
Grid.SetRow(browsx, myGridName.RowDefinitions.Count-1);
You can access any RowDefinition from myGridName.RowDefinitions property to delete it later. But a better idea is to set RowDefinition's Height to zero instead of delete it. With that you don't have to rearrange other controls, moving control in row 3 to row 2 for example because the previous row 2 has been deleted.
This seems like a good case for UniformGrid:
<UniformGrid Grid.Row="0" Grid.Column="2" Columns="1">
<WebBrowser Name="browsc" />
<WebBrowser Name="browsa" />
<WebBrowser Name="browsb" />
</UniformGrid>
UniformGrid ensures that all items have the same size, both width and height. In your case you only want to constrain height, but since there is only one column, all items must have the same width anyway, so this is okay.
Instead of setting up rows, we can just set Columns="1" on the UniformGrid and it will auto-arrange each item on a new row. If you add or remove items, or toggle their Visibility between Visible and Collapsed, all the sizes will be adjusted to fit the space.
Another possibility still using a grid is to bind the height to a converter that uses the visibility of the control it contains to decide on the layout.
Here's an example:
In the XAML file:
<Grid Grid.Row="0" Grid.Column="2" Height="Auto" xmlns:local="clr-namespace:WpfApplication2">
<Grid.Resources>
<local:RowHeightConverter x:Key="RowHeightConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=browsc, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
<RowDefinition Height="{Binding ElementName=browsa, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
<RowDefinition Height="{Binding ElementName=browsb, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
</Grid.RowDefinitions>
<WebBrowser Grid.Row="0" Name="browsc"></WebBrowser>
<WebBrowser Grid.Row="1" Name="browsa" Visibility="Collapsed"></WebBrowser>
<WebBrowser Grid.Row="2" Name="browsb"></WebBrowser>
</Grid>
You can also move the 'xmlns bit up to a top-level window or you may already have it.
In the code behind:
public class RowHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var isVisible = value as bool?;
if (isVisible.HasValue && isVisible.Value)
return new GridLength(1, GridUnitType.Star);
else
return new GridLength(0);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Once you've built the code once, you can change the 'Visibility' of the browsers in the XAML designer and see the changes reflected in the layout.
I have a ListView in a FlipView
<FlipView
x:Name="flipView"
AutomationProperties.AutomationId="ItemsFlipView"
AutomationProperties.Name="Item Details"
TabIndex="1"
Width="Auto"
Grid.Row="2"
Grid.Column="1"
VerticalAlignment="Top"
HorizontalAlignment="Center"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}" Padding="0" VirtualizingStackPanel.VirtualizationMode="Standard">
<FlipView.ItemTemplate>
<DataTemplate>
<!--
UserControl chosen as the templated item because it supports visual state management
Loaded/unloaded events explicitly subscribe to view state updates from the page
-->
<UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Orientation="Vertical" Margin="0,100,0,0">
<ListView x:Name="ListofOptions" Height="400" Width="280"
ItemsSource="{Binding QuestionOptions}" SelectedValue="{Binding Answer,Mode=TwoWay}"
IsEnabled="{Binding IsEnabled,Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<StackPanel.Resources>
<common:AltBackgroundConverter x:Key="BGConvertor" />
</StackPanel.Resources>
<StackPanel.Background>
<SolidColorBrush Color="{Binding IndexWithinParentCollection, Mode=OneWay, Converter={StaticResource BGConvertor}}"></SolidColorBrush>
</StackPanel.Background>
<TextBlock Text="{Binding OptionValue}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
</UserControl>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I write a value conventor of ListView for changing background of alternative row. here is Conventor's code
public class AltBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (!(value is int)) return null;
int index = (int)value;
if (index % 2 == 0)
return Colors.White;
else
return Colors.LightGray;
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
when the listbox is out of FlipView everything is Ok but the Conventor doesn't execute when the ListView is in a FlipView. please advice me.
Created a new Split XAML project in VS2012 and added your converter there and used it in ListView and it was still working after moving the ListView inside a FlipView.
I'm now guessing it's a binding issue, happening because root binding object has changed and one of the bindings not resolved as we expect. have you tried moving the Resources tag to upper level which is the FlipeView?
P.S. This is more of a comment, but I don't have reputation for comments!
Hi I have the following code:
<ListBox x:Name="foldersListBox" Grid.Column="0" MouseLeftButtonUp="foldersListBox_MouseLeftButtonUp"
BorderThickness="0" Height="AUTO"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<DataTemplate>
<Border BorderBrush="LightGray"
BorderThickness="2"
CornerRadius="4">
<Image x:Name="folderImage" Width="70" Height="70" Margin="3" />
</Border>
</DataTemplate>
</ListBox>
Now when I am trying to access folderImage from code behind. I can use the loaded event and typecast the sender as Image type , but I dont want that way,because I want to bind the image source during runtime binding . So even if we will try on loaded event , thatz not going to help as the control wont be loaded .
Help plz.
Thanks,
Subhen
There is quite a bit of detail missing from your question but I'm going to stab at answering anyway. Its highly unlike to answer your question but it might help you see what detail you need to add the question to guide the answers. In turn this answer can be refined. Some iterations down the road you may actually arrive at an answer.
I'm gonna guess that you are binding to a set of object that represent "Folders" but you want programmatically modify the image being presented depending on the state of each object, for example some FolderType property.
On solution to this is to use a value converter, if your images are from a finite set.
public class FolderToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Folder folder = value as Folder;
ImageSource result;
// Logic to determine which ImageSource to use for a folder.
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Now take a look at this XAML:-
<Grid x:Name="LayoutRoot">
<Grid.Resources>
<local:FolderToImageConverter x:Key="ImageConverter" />
</Grid.Resources>
<ListBox x:Name="foldersListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="LightGray" BorderThickness="2" CornerRadius="4">
<Image Source="{Binding Converter={StaticResource ImageConverter}}" Width="70" Height="70" Margin="3" />
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Once you have bound your collection of Folder objects to the ListBox ItemsSource it will display a set of images using the converter to transform the Folder object to the correct ImageSource instance.