【发布时间】:2017-05-07 22:33:09
【问题描述】:
我正在使用MasterDetailPage 创建侧边菜单,菜单项列表是使用ListView 实现的。我想为所选项目制作自定义外观:
- 背景颜色
- 标签的文本颜色
-
ImageSource图标
我该怎么做?
【问题讨论】:
标签: c# android xamarin xamarin.forms xamarin.forms.listview
我正在使用MasterDetailPage 创建侧边菜单,菜单项列表是使用ListView 实现的。我想为所选项目制作自定义外观:
ImageSource 图标我该怎么做?
【问题讨论】:
标签: c# android xamarin xamarin.forms xamarin.forms.listview
我在列表视图项中创建字段 IsActive 并使用绑定到该字段的 DataTrigger 并设置我需要的所有属性。
我将所选项目的颜色设置为StackLayout,所以我只是隐藏了ListView 的原始选择颜色(在Android 上为橙色)
<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>
注意这个类应该实现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));
}
}
然后在母版页代码后面我使用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;
}
}
【讨论】: