dath
dath

Reputation: 915

How to add a ListViewItem which contains a Grid, StackPanel and a TextBlock

I have a ListView. I need to add ListViewItems programatically that contain a Textblock nested inside of a StackPanel, nested inside of a Grid (For the purpose of formatting the text). I am relatively new to WPF and I cannot find an answer. Here is the code that I would like each ListViewItem to have once added:

<ListViewItem Padding="15">
    <Grid Width="1285">
        <StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Width="Auto">
            <TextBlock Text="ITEM" VerticalAlignment="Center" />
        </StackPanel>
    </Grid>
</ListViewItem>

Here is an image to demonstrate what I am trying to do.The code above puts the ListViewItem in the middle, but by using a Grid and a StackPanel, I was able to center the text (StackPanel was actually for the purpose of adding an icon alongside it but I've temporarily taken that out. If someone knows how to do this better then by all means tell me.

enter image description here

Upvotes: 0

Views: 81

Answers (1)

Sach
Sach

Reputation: 10393

So, what you need is a UserControl, which will be used to display each item in your ListView. So you must design your user control the way you want it to look; so if you need a TextBlock inside a panel inside a grid, that's what you must do.

<UserControl x:Class="SOWPF.MyListViewItem"
             ....
             mc:Ignorable="d" 
             d:DesignHeight="48" d:DesignWidth="250">
    <Grid>
        <StackPanel Orientation="Horizontal" Width="250" Height="36" Margin="10" Background="PeachPuff">
            <TextBlock Background="White" Width="200" Height="32" Margin="2" Text="{Binding DisplayText}"/>
        </StackPanel>
    </Grid>
</UserControl>

To display data, you must have a class with public properties. So I have this simple class with one public string property, which will contain the text you want to display in the TextBlock. The data binding on the user control refers to this; DisplayText is the public string property:

public class DisplayData
{
    public string DisplayText { get; set; }
}

Now in your View, you must use a ContentControl inside your ListView to display your UserControl dynamically.

<Window x:Class="SOWPF.MainWindow"
        ....
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListView>
            <ItemsControl ItemsSource="{Binding DisplayList}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <local:MyListViewItem/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ListView>
    </Grid>
</Window>

And here's your code behind. I did it this way for convenience, but you really should use a ViewModel.

public partial class MainWindow : Window
{
    public List<DisplayData> DisplayList { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        DisplayList = new List<DisplayData>
        {
            new DisplayData() { DisplayText = "A" },
            new DisplayData() { DisplayText = "B" },
            new DisplayData() { DisplayText = "C" }
        };

        DataContext = this;
    }
}

Result:

enter image description here


EDIT (After OP edited the question)

If all you want to do is center text, you can get rid of extra controls and simply use TextAlignment=Center in your TextBlock.

<UserControl x:Class="SOWPF.MyListViewItem"
             ....
             mc:Ignorable="d" 
             d:DesignHeight="48" d:DesignWidth="250">
    <TextBlock Background="LightCoral" Width="200" Height="32" Margin="2" Text="{Binding DisplayText}"
               TextAlignment="Center"/>
</UserControl>

And it'll look like this:

enter image description here

Upvotes: 1

Related Questions