ListView中所选项目的粗体标签?

时间:2017-03-21 17:07:43

标签: c# xaml data-binding xamarin.forms

我有以下XAML:

<?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:local="clr-namespace:StyleLabelInViewCell" x:Class="StyleLabelInViewCell.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:MainVM x:Key="MainVm" />
            <local:IsSelectedToStyle x:Key="IsSelectedToStyle" />
            <Style x:Key="SelectedStyle" TargetType="Label">
                <Setter Property="FontAttributes" Value="Bold" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout BindingContext="{StaticResource MainVm}">
        <ListView x:Name="ChildListView" VerticalOptions="Center" ItemsSource="{Binding Chidren}" SelectedItem="{Binding SelectedVm}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell x:Name="ChildViewCell">
                        <ViewCell.View>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>

                                <Button Text="&lt;" />

                                <Label 
                                    Grid.Column="1" 
                                    Text="{Binding Name}" 
                                    FontAttributes="{Binding Source={x:Reference ChildListView}, Path=SelectedItem.Id, Converter={StaticResource IsSelectedToStyle}, ConverterParameter={Binding Path=Id}}" 
                                />

                                <Button Grid.Column="2" Text="&gt;"  />
                            </Grid>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

以下代码:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using Xamarin.Forms;

namespace StyleLabelInViewCell {
    public class MainVM : INotifyPropertyChanged {
        public MainVM() {
            Chidren = new ObservableCollection<ChildVM> {
                new ChildVM(1, "Item 1"),
                new ChildVM(2, "Item 2"),
                new ChildVM(3, "Item 3"),
                new ChildVM(4, "Item 4"),
                new ChildVM(5, "Item 5"),
                new ChildVM(6, "Item 6")
            };
        }

        public ObservableCollection<ChildVM> Chidren { get; }

        private ChildVM selectedVm;
        public ChildVM SelectedVm {
            get { return selectedVm; }
            set {
                if (!ReferenceEquals(selectedVm, value)) {
                    selectedVm = value;
                    OnPropertyChanged(nameof(SelectedVm));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class ChildVM {
        public ChildVM() { }

        public ChildVM(int id, string name) {
            Id = id;
            Name = name;
        }

        public int Id { get; }

        public string Name { get; }
    }

    public sealed class IsSelectedToStyle : IValueConverter {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            var selectedId = (int)value;
            var currentItemId = (int)parameter; // This ends up being Xamarin.Forms.Binding instance

            return selectedId == currentItemId ? Application.Current.MainPage.Resources["SelectedStyle"] : null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotSupportedException();
        }
    }
}

ItemTemplate正在渲染当前选定的行时,我正在尝试加粗标签。问题是,ConverterParameter作为Xamarin.Forms.Binding实例发送,当我预期到另一个整数时。

有没有办法从绑定中获取值而不是绑定?还是有另一种方法可以完成我想要做的事情吗?

1 个答案:

答案 0 :(得分:1)

我认为你可以看看这个post

我更新了repo。现在还有一个用于FontAttributes属性的绑定

<ListView SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding List}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <Label Text="{Binding Name}" FontAttributes="{Binding Selected, Converter={StaticResource cnvInvertFontAttribute}}}" TextColor="{Binding Selected, Converter={StaticResource cnvInvert}}}" FontSize="18"></Label>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

选择行时,在VM

中设置Selected属性
    public MyModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if (_selectedItem != null)
                _selectedItem.Selected = false;

            _selectedItem = value;

            if (_selectedItem != null)
                _selectedItem.Selected = true;
        }
    }

和IValueConverter转换布尔值&#34; Selected&#34;属性到FontAttribute

public class SelectedToFontAttributeConverter : IValueConverter
{

    #region IValueConverter implementation

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            if ((Boolean)value)
                return FontAttributes.Bold;
            else
                return FontAttributes.None;
        }
        return FontAttributes.None;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}