Melon NG
Melon NG

Reputation: 3004

How can I clear strange spacing of listviewitem in Xamarin.WPF?

Here is the code in XAML of Xamarin project:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <ListView ItemsSource="{Binding TestList}" SeparatorVisibility="None" HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.View>
                        <ContentView BackgroundColor="Red">
                            <Label Text="{Binding TestName}"></Label>
                        </ContentView>
                    </ViewCell.View>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Here is code-behind of Xamarin project:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = this;
            TestList.Add(new Test() { TestName = "aaa" });
            TestList.Add(new Test() { TestName = "bbb" });
            TestList.Add(new Test() { TestName = "ccc" });
            TestList.Add(new Test() { TestName = "ddd" });
        }
        public ObservableCollection<Test> TestList { get; set; } = new ObservableCollection<Test>();
        public class Test
        {
            public string TestName { get; set; }
        }
    }
}

Here is the Style of WPF project:

<Application x:Class="App1.WPF.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:App1.WPF"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style x:Key="LvItemStyle" TargetType="ListViewItem">
            <Setter Property="Margin" Value="0"></Setter>
            <Setter Property="Padding" Value="0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ContentPresenter Margin="0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style TargetType="ListView" x:Key="LvStyle">
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Foreground" Value="Transparent"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="0"></Setter>
            <Setter Property="Margin" Value="0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListView">
                        <ScrollViewer Focusable="false" Padding="0" Margin="0" Background="Green">
                            <ItemsPresenter Margin="0"/>
                        </ScrollViewer>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsGrouping" Value="true"/>
                                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

And here is the MyListView.cs in WPF project:

using App1.WPF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using Xamarin.Forms.Platform.WPF;

[assembly: ExportRenderer(typeof(Xamarin.Forms.ListView), typeof(MyListView))]
namespace App1.WPF
{
    class MyListView : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
            foreach (var item in Control.Children)
            {
                if (item is ListView)
                {
                    var list = item as ListView;
                    list.Style = App.Current.Resources["LvStyle"] as System.Windows.Style;
                    list.ItemContainerStyle = App.Current.Resources["LvItemStyle"] as System.Windows.Style;
                }
            }
        }
    }
}

Here is the screen capture in Android, it fits well.
enter image description here

And here is the screen capture in WPF. There is a strange spacing in the left of each listviewitem.
enter image description here

As you see, in spite I have added so many margin="0" and padding="0" above in the ListView/ListViewItem style of the WPF project, it doesn't work at all.

What's the problem? How can I solve this? Thank you.

Upvotes: 0

Views: 176

Answers (1)

Tam Bui
Tam Bui

Reputation: 3038

Not 100% sure the root cause of the issue, but I suspect it has something to do with how the System.Windows.ListViewItem's style is trying to present the Xamarin.Forms.ViewCell's content, and the presenter is adding some margin.

I was able to fix it by editing the ContentPresenter of your ListViewItem's style (btw, remove all your other margins and paddings to make sure none of them override this setting):

        <Style x:Key="LvItemStyle" TargetType="ListViewItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ContentPresenter Margin="-5,0,0,0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

enter image description here

Upvotes: 1

Related Questions