Using the default styling for everything, I can't get the heart icon to be vertically centered in this listview.
To reproduce the problem just create a super simple brand new WPF app and add MaterialDesginInXamlToolkit ResourceDictionary
s to App.xaml, then add the following code:
MainWindow.xaml
<Window
x:Class="WpfApp1.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:WpfApp1"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{DynamicResource MaterialDesignFont}"
TextElement.FontSize="13"
TextElement.FontWeight="Regular"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Ideal"
TextOptions.TextRenderingMode="Auto"
mc:Ignorable="d">
<Window.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<ListView
x:Name="listview"
VerticalContentAlignment="Center"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Path
Width="{Binding Height, Mode=OneWay, RelativeSource={RelativeSource Self}}"
Height="12"
VerticalAlignment="Center"
Fill="Red"
Stretch="Uniform"
Stroke="White"
StrokeThickness="1"
Visibility="{Binding IsLoved, ConverterParameter=True, Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}">
<Path.Data>
<PathGeometry Figures="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
</Path.Data>
</Path>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="330" Header="Title">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
var items = new List<Item>();
items.Add(new Item { IsLoved = true, Title = "This is a test" });
items.Add(new Item { IsLoved = false, Title = "This is a test" });
items.Add(new Item { IsLoved = true, Title = "This is a test" });
items.Add(new Item { IsLoved = false, Title = "This is a test" });
items.Add(new Item { IsLoved = true, Title = "This is a test" });
this.listview.ItemsSource = items;
}
}
public class Item
{
public bool IsLoved { get; set; }
public string Title { get; set; }
}
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool isVisible;
try
{
isVisible = System.Convert.ToBoolean(value);
}
catch
{
return DependencyProperty.UnsetValue;
}
var falseVisibility = parameter == null
? Visibility.Collapsed
: Visibility.Hidden;
return isVisible
? Visibility.Visible
: falseVisibility;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
}
Material Design's default ListViewItem style leaves ListViewItem.VerticalContentAlignment unchanged from its default value of Top, instead of using the value set by the parent ListView. We can fix that like so:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource MaterialDesignGridViewItem}">
<Setter
Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType=ListView}}"
/>
</Style>
</ListView.ItemContainerStyle>
Make it Stretch
instead of Center
if you have items that need to fill the row vertically (e.g. borders, colored backgrounds). In that case, you'll have to explicitly set VerticalAlignment="Center"
in all the templates, as you're now doing with the Path.
MaterialDesignGridViewItem
is a style defined here.
On line 155 we find the VerticalContentAlignment of the GridViewRowPresenter which presents the row content. It has a TemplateBinding which uses the VerticalContentAlignment defined for the ListViewItem. That Style has no Setter for that property, so it will just use the default value of Control.VerticalContentAlignment, which is VerticalAlignment.Top
. default(VerticalAlignment)
happens to be Top
.
<GridViewRowPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />