WPF binding to a UserControl property - c#

I have a list of items, each of which contains a display property of a type inheriting from a user control. The idea is each inheriting class can decide for itself what it wants to display for the user. The items are themselves arranged in a DataTemplate for a tab control... something like...
<TabControl ItemsSource="{Binding FooList}">
<TabControl.ItemTemplate>
<DataTemplate>
<TabItem Header="{Binding Name}">
???
</TabItem>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
And the classes in the foo observablecollection look like...
public class IFoo
{
public String Name { get; set; }
public UserControl Display { get; set; }
...
}
What I can't figure out is how to add the display property where the ??? is in the XAML. Is there a way to do this (trying to avoid doing it from the code behind)?

What you need to do is use the ItemContainerStyle property of TabControl:
<TabControl ItemsSource="{Binding FooList}">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Name}" />
<Setter Property="Content" Value="{Binding Display}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>

Related

How do I select a new ListBoxItem in C# WPF after I just inserted it automatically

I have the following problem with my calculator app which I'm doing in the MVVM pattern.
I'm redoing the Windows 10 Calculator in Standard Mode. I made an ObservableCollection of MemoryItem.
MemoryItem is a class that contains an int for the Index, a double for the value and a RelayCommand for the MemoryButtons.
Basically it looks like this and is connected to my ViewModel:
public class MemoryItem
{
public double MemoryItemValue { get; set; }
public int SelectedMemoryItemIndex { get; set; }
public RelayCommand MemoryItemChange { get; set; }
}
So I've binded the SelectedMemoryItemIndex Property to the SelectedItemIndex in WPF.
My ListBox looks like this:
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource MemoryListBoxStyle}"
Visibility="{Binding MemoryVisibility}" ItemsSource="{Binding MemoryCollection}"
SelectedItem="{Binding SelectedMemoryItem}" SelectionMode="Extended" SelectedIndex="{Binding SelectedMemoryItemIndex}"
HorizontalContentAlignment="Right"/>
While the style of it looks like this:
<Style x:Key="MemoryListBoxStyle" TargetType="ListBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<UniformGrid Rows="2" Margin="5">
<TextBlock Style="{StaticResource DisplayStyle}" Text="{Binding MemoryItemValue}" FontSize="20"/>
<DockPanel LastChildFill="False">
<Button Content="MC" Style="{StaticResource MemoryItemButton}"
Command="{Binding MemoryItemChange}" CommandParameter="{x:Static md:MemoryUsage.Clear}"/>
<Button Content="M+" Style="{StaticResource MemoryItemButton}"
Command="{Binding MemoryItemChange}" CommandParameter="{x:Static md:MemoryUsage.Add}"/>
<Button Content="M-" Style="{StaticResource MemoryItemButton}"
Command="{Binding MemoryItemChange}" CommandParameter="{x:Static md:MemoryUsage.Substract}"/>
</DockPanel>
</UniformGrid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
The bindings work BUT I don't know how to have the new MemoryItem selected after Inserting the new MemoryItem and deleting the new one. Is there a better of way inserting the new item? ObservableCollection doesn't include a method to update a specific item (as far as I know).
This is the method I'm using to add the value to the MemoryItemValue and insert it in my Collection:
case MemoryUsage.Add:
if (SelectedMemoryItemIndex == -1)
{
SelectedMemoryItemIndex = 0;
}
MemoryItemValue += Eingabe1;
MemoryCollection.Insert(SelectedMemoryItemIndex +1, MItem);
MemoryCollection.RemoveAt(SelectedMemoryItemIndex);
break;
This way it worked but I always have to select the new inserted MemoryItem.
I'm thankful for ANY help provided by you.
Please keep in mind that I'm a beginner in programming and this is my first SO question ever.
Here is a post that helps answer this question.
But basically:
Create an IsSelected property on your MemoryItem class and bind ListBoxItem.IsSelected to that property.
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
When you want your new item selected, just set IsSelected to true.
IsSelected = true;
And shazam! It should work.
Here is code copied from another answer that may give you more information.
<ListBox ItemsSource="{Binding Items, Source={StaticResource ViewModel}}"
SelectionMode="Extended">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsItemSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ItemText}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Forgive me for leaving that example exactly as I found it.

How to correctly bind a ViewModel (which Include Separators) to WPF's Menu?

I'm using MVVM and I want to data bind my list of MenuViewModels to my maim menu. Which consists of a set of menu items and separators.
Here's my MenuItemViewModel code:
public interface IMenuItemViewModel
{
}
[DebuggerDisplay("---")]
public class SeparatorViewModel : IMenuItemViewModel
{
}
[DebuggerDisplay("{Header}, Children={Children.Count}")]
public class MenuItemViewModel : IMenuItemViewModel, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MenuItemViewModel(string header, ICommand command, ImageSource imageSource)
{
Header = header;
Command = command;
ImageSource = imageSource;
Children = new List<IMenuItemViewModel>();
}
public string Header { get; private set; }
public ICommand Command { get; private set; }
public ImageSource ImageSource { get; private set; }
public IList<IMenuItemViewModel> Children { get; private set; }
}
And my Main window looks like this:
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type ViewModel:MenuItemViewModel}"
ItemsSource="{Binding Children}">
<MenuItem Header="{Binding Header}"
Command="{Binding Command}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type ViewModel:SeparatorViewModel}">
<Separator />
</DataTemplate>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top"
ItemsSource="{Binding MenuItems}">
</Menu>
</DockPanel>
Should be very simple stuff. Unfortunately, either the menu item looks wrong or the separator is an empty menuItem (depending on what I've tried).
So, how do I get my Menu to find my two DataTemplates?
Solved my own question
After spending several hours searching the web, I found lots of examples that work against the WPF's natural intentions but none that worked with it.
Here's how to work with the Menu control and not against it...
A little Background
WPF's Menu control will normally auto create MenuItem objects for you when it is binded to a POCO collection, using the ItemsSource property.
However, this default behavior can be overridden! Here's how...
The Solution
First, you must create a class that derives from ItemContainerTemplateSelector. Or use the simple class I've created:
public class MenuItemContainerTemplateSelector : ItemContainerTemplateSelector
{
public override DataTemplate SelectTemplate(object item, ItemsControl parentItemsControl)
{
var key = new DataTemplateKey(item.GetType());
return (DataTemplate) parentItemsControl.FindResource(key);
}
}
Second, you must add a reference to the MenuItemContainerTemplateSelector class to your Windows resources object, like so:
<Window.Resources>
<Selectors:MenuItemContainerTemplateSelector x:Key="_menuItemContainerTemplateSelector" />
Third, you must set two properties (UsesItemContainerTemplate, and ItemContainerTemplateSelector) on both the Menu and the MenuItem (which is defined in the HierarchicalDataTemplate).
Like so:
<HierarchicalDataTemplate DataType="{x:Type ViewModel:MenuItemViewModel}"
ItemsSource="{Binding Children}">
<MenuItem Header="{Binding Header}"
Command="{Binding Command}"
UsesItemContainerTemplate ="true"
ItemContainerTemplateSelector=
"{StaticResource _menuItemContainerTemplateSelector}"/>
</HierarchicalDataTemplate>
<Menu DockPanel.Dock="Top"
ItemsSource="{Binding MenuItems}"
UsesItemContainerTemplate="True"
ItemContainerTemplateSelector=
"{StaticResource _menuItemContainerTemplateSelector}">
</Menu>
Why it Works
For optimization purposes, the Menu uses the UsesItemContainerTemplate flag (which has a default value of false) to skip the DataTemplate lookup and just returns a normal MenuItem object. Therefore, we needed to set this value to true and then our ItemContainerTemplateSelector works as expected.
Happy Coding!
A solution without the TemplateSelector:
provide ItemContainerTemplates instead of the DataTemplates :
<ContextMenu ItemsSource="{Binding Path=MenuItems}" UsesItemContainerTemplate="True">
<ContextMenu.Resources>
<ResourceDictionary>
<ItemContainerTemplate DataType="{x:Type ViewModel:MenuItemViewModel }">
<MenuItem Header="{Binding Path=Header}" Command="{Binding Path=Command}" UsesItemContainerTemplate="True">
<MenuItem.Icon>
<Image Source="{Binding Path=ImageSource}"/>
</MenuItem.Icon>
</MenuItem>
</ItemContainerTemplate>
<ItemContainerTemplate DataType="{x:Type ViewModel:SeparatorViewModel}">
<Separator >
<Separator.Style>
<Style TargetType="{x:Type Separator}" BasedOn="{StaticResource ResourceKey={x:Static MenuItem.SeparatorStyleKey}}"/>
</Separator.Style>
</Separator>
</ItemContainerTemplate>
</ResourceDictionary>
</ContextMenu.Resources>
</ContextMenu>
Notes:
I haven't tried Children
the separator styled wrong: I had to manually re-apply the style
Another approach is to:
have a Boolean property on your menu item ViewModel that indicates whether an item is a separator or not
use a trigger based on this property to change the ControlTemplate of the MenuItem so that it uses a Separator control instead
Like so:
<Menu ItemsSource="{Binding MenuItems}">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="Command" Value="{Binding Command}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSeparator}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<HierarchicalDataTemplate DataType="{x:Type ViewModel:MenuItemViewModel}"
ItemsSource="{Binding Children}" />
</Menu.Resources>
</Menu>

Item not changing group in a grouped listview

I have a listView in which I show a collection of Vehicles which are grouped by their MaintenanceState. If the MaintenanceState of the Vehicle updates I expect it to change group. The collection itself is correctly updated, however the view does not update accordingly. Below is some of my code, maybe someone can help me getting this to work.
This is my CollectionViewSource managing my groupings
<CollectionViewSource x:Key="GroupedVehicles" IsLiveGroupingRequested="True" Source="{Binding ItemCollection}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="MaintenanceState" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
Here is my ListView
<ListView ItemContainerStyle="{DynamicResource VehicleItemContainerStyle}"
ItemsSource="{Binding Source={StaticResource GroupedVehicles}}"
SelectedItem="{Binding SelectedItem}"
SelectionMode="Single"
Style="{DynamicResource VehiclesListViewStyle}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<Expander Header="{Binding Path=Name}"
IsExpanded="True"
Style="{DynamicResource VehicleListSectionExpanderStyle}">
<ItemsPresenter />
</Expander>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Number}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is what I do on my ViewModel
Vehicle updatedVehicle = new Vehicle(vehicleNumber, MaintenanceStateEnum.Running);
ItemCollection[index] = updatedVehicle;
The ItemCollection is of type ObservableCollection<Vehicle> and I make sure to only add, remove or replace Vehicles.
The MaintenanceStateEnum has the following values: InMaintenance, MarkedForMaintenance and Running.
This is what my Vehicle looks like
public class Vehicle
{
public Vehicle(int number, MaintenanceStateEnum state) {}
public int Number { get; private set; }
public MaintenanceStateEnum MaintenanceState { get; private set; }
}
So my problem:
If I have Vehicle(3, MaintenanceStateEnum.MarkedForMaintenace) and it is updated to Vehicle(3, MaintenanceStateEnum.InMaintenance) it does not change from the grouping MarkedForMaintenance to the grouping InMaintenance.
Interesting is that it does get removed from the MarkedForMaintenance grouping (the view even leaves a space as if the object is still there).
Does anyone know how I can fix my problem?
I think the issue here is that the view does not know that the collection has changed. You could try to change your container from ItemCollection to ObservableCollection which implements both INotifyCollectionChanged and INotifyPropertyChanged.

What is the proper way to designate the data context and bind hierarchical data in the treeview?

I have a fairly simple data model:
public class ServiceModel
{
private static readonly IQmiServiceManager ServiceManager = Bootstrap.Instance.DomainManager.QmiServiceManager;
private string _serviceName;
private ObservableCollection<string> _serviceMessages;
public string Name
{
get { return _serviceName; }
private set { _serviceName = value.ToUpper(); }
}
public ObservableCollection<string> Messages
{
get { return _serviceMessages; }
private set { _serviceMessages = value; }
}
public ServiceModel(string ServiceName, IList<string> ServiceMessages)
{
Name = ServiceName;
Messages = new ObservableCollection<string>(ServiceMessages);
}
}
...which is encapsulated in this view model:
public class ServiceCollectionViewModel
{
private readonly ObservableCollection<ServiceModel> _serviceModels = new ObservableCollection<ServiceModel>();
public ObservableCollection<ServiceModel> ServiceModels
{
get { return _serviceModels; }
}
}
I have the following treeview xaml definition:
<TreeView Name="ServiceTree" Grid.Row="1" ItemsSource="{Binding Services}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding}">
<TextBlock Text="{Binding Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Messages}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Nothing is being output in the tree. I have tried following several tutorials on hierarchical data-binding but I'm simply having difficulty understanding the proper technique for my specific situation.
Also, how should the data-context be set? I am setting the context as follows within the code-behind of the view:
public partial class ServiceView : UserControl
{
private readonly ServiceCollectionViewModel _serviceCollection = new ServiceCollectionViewModel();
public ObservableCollection<ServiceModel> Services
{
get { return _serviceCollection.ServiceModels; }
}
public ServiceView()
{
InitializeComponent();
DataContext = _serviceCollection;
_serviceCollection.LoadServices();
}
}
You seem to be very confused. You're trying to data bind to your ServiceView.Services property, so what is the ServiceCollectionViewModel class for? The sole purpose of a view model is to provide all of the data (and functionality) required for its view.
Now we can go different routes... it all depends what you actually want. If you want to data bind from outside the UserControl to the ServiceView.Services property, then you must declare the Services property as a DependencyProperty. Inside your UserControl, you would then data bind to the property using a RelativeSource Binding like this:
Outside:
<YourPrefix:ServiceView Services="{Binding YourExternalViewModelProperty}" />
Inside:
<TreeView Name="ServiceTree" Grid.Row="1" ItemsSource="{Binding Services,
RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:ServiceView}}}">
...
</TreeView>
With this method, there is no need to set the DataContext to anything as we are using RelativeSource to set the data source. Alternatively, you could set the DataContext to either the internal UserControl code behind, or an instance of a view model (from either inside or outside) and then normally data bind like this:
<TreeView Name="ServiceTree" Grid.Row="1" ItemsSource="{Binding Services}">
...
</TreeView>
So, to recap, if you set the DataContext to an instance of an object, then your Binding Paths look at the properties in that object to resolve themselves. Otherwise, if you set a RelativeSource (or ElementName) in your Binding Path, then you are changing the data source for that Binding only and your Binding Paths should be properties from those objects instead.
UPDATE >>>
The HierarchicalDataTemplate Class is basically a slight extension on the regular old DataTemplate class and can be thought of a DataTemplate with an ItemsSource property. Therefore, if you can define the content of a DataTemplate, then you can define the content of a HierarchicalDataTemplate... just make sure to set the HierarchicalDataTemplate.ItemsSource property to a valid collection property... in your case, the Messages property:
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type YourPrefix:ServiceModel}"
ItemsSource="{Binding Messages}"> <!-- Collection Property In ServiceModel -->
<TextBlock Text="{Binding Name}" /> <!-- Property In ServiceModel -->
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
If you're not too clear on DataTemplate, take a look at the Data Binding Overview page on MSDN.
You have a number of issues here.
ItemsSource binding should be to ServiceModels and not Services, because that is the name of the property in your ServiceCollectionViewModel. SO this way you get the top-level items.
You are trying to bind inside your items' style to IsExpanded and IsSelected properties, but there are no such properties on your view-models.
Inside your HierarchicalDataTemplate you bind the ItemsSource property directly to the DataContext of the TreeViewItem which in this case is ServiceModel. Either make the ServiceModel implement IEnumerable<string> exposing your messages, or bind to Messages property directly:
The second level HierarchicalDataTemplate binds the Text property to Messages, but the DataContext of this level is of String type, having no Messages property. So here you should bind to the data context itself:
Regarding the data context, you better initialize it in XAML, using static resource. Also, much cleaner approach to define the hierarchical data templates is using implicit templates, based on the item types. Because you really don't want to define hierarchical templates inline for a greater number of hierarchy levels (say: 4, 5). See below the completely fixed XAML:
<Grid>
<Grid.Resources>
<!--Data context for the whole Grid-->
<myNamespace:ServiceCollectionViewModel x:Key="MyViewModel" />
</Grid.Resources>
<TreeView Name="ServiceTree"
DataContext="{StaticResource MyViewModel}"
ItemsSource="{Binding ServiceModels}">
<TreeView.Resources>
<!--Implicit style for TreeViewItem, IsExpanded and IsSelected have no binding because
they are not used by view-models-->
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
<!--Template for the first level items-->
<HierarchicalDataTemplate DataType="{x:Type myNamespace:ServiceModel}" ItemsSource="{Binding Messages}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<!--Template for the second level, due to the fact that String is not hierarchical
regular DataTemplate is enough-->
<DataTemplate DataType="{x:Type system:String}">
<TextBlock Text="{Binding}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
I believe this one is both more understandable and, consequently, more maintainable.

Is it possible to bind a list of objects?

I have the following class:
public class MyClass
{
public MyClass()
{
OtherClass = new List<OtherClass>();
}
public List<OtherClass> OtherClass { get; set; }
}
OtherClass contains:
public class OtherClass
{
public OtherClass ()
{
}
public string Name { get; set; }
}
and the following xaml MyView:
<DataTemplate DataType="{x:Type Framework:MyClass}">
<StackPanel>
<Label FontSize="20" Content="{Binding Path=OtherClass.Name}" />
</StackPanel>
</DataTemplate>
in MyWindow referencing MyView:
<TabItem Header="My Class">
<Views:MyView DataContext="{Binding Path=MyClass}" />
</TabItem>
I have seen other examples of binding nested properties which suggest that Binding Path this way (ie, OtherClass.Name) works fine for a single object. However, I am binding a list of objects rather than a single object (in my example, a list of OtherClass).
Is it possible to bind a list of objects?
If you want to create DataTemplate for MyClass then you need to use some form of ItemsControl to display OtherClass list property
<DataTemplate DataType="{x:Type Framework:MyClass}">
<ItemsControl ItemsSource="{Binding OtherClass}" DisplayMemberPath="Name"/>
</DataTemplate>
also OtherClass.Name must be a public property and not private as it is at the moment
public class OtherClass
{
public OtherClass ()
{
}
public string Name { get; set; }
}
EDIT
DisplayMemberPath is the easiest way to display single property but if you want to display more then one property from OtherClass class, or change how it's formatted then you need to define ItemsControl.ItemTemplate instead and tell ItemsControl how to display each item
<ItemsControl ItemsSource="{Binding OtherClass}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<!-- more properties that you want to display -->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What you'll likely want to do here is make a ItemsControl, where each item of your OtherClass list will be prepresented by one item. Your ItemTemplate will dictate what each item in that list is to display, in your case the ItemTemplate will contain a Label which is bound to the Name property. See below:
<ItemsControl ItemsSource="{Binding OtherClass}" DataType="{x:Type Framework:MyClass}">
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
(See a more complete example here)
If you are binding to a "list" of objects, the list must be bound to a control that has an ItemsSource property. These types of controls are able to bind to collections so that the inner DataContext of the control is the list's type. In your case, if you bind to the OtherClass property (the list), the DataContext scope will be of Type 'OtherClass' where you can then bind to its properties explicitly.
As others have mentioned, you can bind to an ItemsControl, but can also bind to a ListBox, ListView, DataGrid, TreeView, etc.
<!-- Using ItemsControl -->
<ItemsControl ItemsSource="{Binding OtherClass}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Using ListBox-->
<ListBox ItemsSource="{Binding OtherClass}">
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Categories