简体   繁体   English

Xamarin ListView所选项目的外观

[英]Xamarin ListView selected item appearance

I am creating side menu using MasterDetailPage and the list of menu items is implemented using ListView . 我使用MasterDetailPage创建侧面菜单,并且使用ListView实现菜单项的列表。 I want to make custom appearance for selected item: 我想为所选项目做自定义外观:

  • Background color 背景颜色
  • Label's text color 标签的文字颜色
  • ImageSource for icon 图标的ImageSource

How can I do this? 我怎样才能做到这一点?

I create field IsActive in my list view item and use DataTrigger binded to this field and set all properties what I need. 我在列表视图项中创建字段IsActive ,并使用绑定到该字段的DataTrigger并设置所需的所有属性。

In XAML 在XAML中

I set color of selected item to the StackLayout , so I just hide original selected color of ListView (orange in my case on Android) 我将选定项目的颜色设置为StackLayout ,所以我只隐藏了ListView原始选定颜色(在我的情况下为橙色)

<ListView.ItemTemplate>

                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal"
                                     Padding="16, 0, 16, 0"
                                     HeightRequest="48">

                            <StackLayout.Triggers>
                                <DataTrigger TargetType="StackLayout"
                                                 Binding="{Binding IsActive}"
                                                 Value="True">
                                    <Setter Property="BackgroundColor" Value="{StaticResource menu-background-active}"/>
                                </DataTrigger>
                            </StackLayout.Triggers>

                            <Image Source="{Binding IconSource}"
                                   VerticalOptions="Center"
                                   WidthRequest="20"/>
                            <Label Text="{Binding Title}" TextColor="Black"
                                   VerticalOptions="Center"
                                   Margin="36,0,0,0">
                                <Label.Triggers>
                                    <DataTrigger TargetType="Label"
                                                 Binding="{Binding IsActive}"
                                                 Value="True">
                                        <Setter Property="TextColor" Value="{StaticResource menu-text-active}"/>
                                    </DataTrigger>
                                </Label.Triggers>
                            </Label>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>

   </ListView.ItemTemplate>

ItemsSource item 项目源项目

Note that this class should implement INotifyPropertyChanged 请注意,此类应实现INotifyPropertyChanged

public class MasterPageItem : INotifyPropertyChanged
{
    private string _title;
    private string _iconSource;
    private bool _isActive;


    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            OnPropertyChanged(nameof(Title));
        }
    }

    /// <summary>
    /// Set or return icon file
    /// If IsActive == true
    /// will add suffix "_active" to return value,
    /// 
    /// Note:
    /// Icons file should be the pair"
    ///  - icon_name.png
    ///  - icon_name_active.png
    /// 
    /// </summary>
    public string IconSource
    {
        get
        {
            if (!IsActive)
                return _iconSource;

            return Path.GetFileNameWithoutExtension(_iconSource) + "_active" + Path.GetExtension(_iconSource);
        }
        set
        {
            _iconSource = value;
            OnPropertyChanged(nameof(IconSource));
        }
    }

    /// <summary>
    /// Is menu item is selected
    /// </summary>
    public bool IsActive
    {
        get { return _isActive; }
        set
        {
            _isActive = value;
            OnPropertyChanged());
        }
    }

    public Type TargetType { get; set; }

    // Important for data-binding

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

Then in the master page code behind I use ItemSelected event to change the IsActive property 然后,在后面的母版页代码中,我使用ItemSelected事件更改IsActive属性

private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        var item = e.SelectedItem as MasterPageItem;
        var items = listView.ItemsSource as IList<MasterPageItem>;

        //Select current item and deselect others
        for(int i = 0; i<items.Count; i++)
            items[i].IsActive = items[i] == item;

        if (item != null)
        {
            ItemSelected?.Invoke(this, item.TargetType);
            _activePage = item.TargetType;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM