集团Swtich Xamarin形式

时间:2017-09-15 14:54:30

标签: xamarin xamarin.ios xamarin.forms xamarin.android

我有一个Listview,它在每一行中创建动态数据和一个开关,我想要的是当我切换一个开关时其他人解开。 这可能吗?

示例:

</a>

2 个答案:

答案 0 :(得分:2)

注意: 这个解决方案对我来说是一个实验 - 所以我建议,如果你决定实现这个,请使用它小心。

这里的目的是扩展Switch以便能够充当分组单选按钮。

第一步是在项目中创建IsToggledIsChecked或类似属性,作为每个列表项的BindingContext。您可以实现如下界面:

public interface IToggableItem 
{ 
    string GroupName { get; } //not mandatory, only added to support grouped lists
    bool IsChecked { get; set; } 
}

第二步是扩展Switch以了解items-list。我们可以通过添加GroupContext可绑定属性来实现这一点 - 它基本上代表父列表视图的ItemsSource

切换开关时,它会遍历items-list,将属性设置为false其他项目。

例如:

public class GroupedSwitch : CustomSwitch
{
    public static readonly BindableProperty IsGroupingEnabledProperty =
        BindableProperty.Create(
            "IsGroupingEnabled", typeof(bool), typeof(GroupedSwitch),
            defaultValue: default(bool));

    public bool IsGroupingEnabled
    {
        get { return (bool)GetValue(IsGroupingEnabledProperty); }
        set { SetValue(IsGroupingEnabledProperty, value); }
    }

    public static readonly BindableProperty GroupContextProperty =
        BindableProperty.Create(
                    "GroupContext", typeof(IEnumerable), typeof(GroupedSwitch),
                    defaultValue: default(IEnumerable));

    public IEnumerable GroupContext
    {
        get { return (IEnumerable)GetValue(GroupContextProperty); }
        set { SetValue(GroupContextProperty, value); }
    }

    protected override void OnPropertyChanged(string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);

        if (propertyName != nameof(IsToggled))
            return;

        if (IsToggled != true || GroupContext == null)
            return;

        var currentItem = BindingContext as IToggableItem;
        if (currentItem == null)
            return;

        if (IsGroupingEnabled)
        {
            var groupList = GroupContext as IEnumerable<IGrouping<string, IToggableItem>>;
            var currentGroup = groupList.FirstOrDefault(x => x.Key == currentItem.GroupName);
            if (currentGroup != null)
                foreach (var item in currentGroup)
                {
                    if (item != currentItem)
                        item.IsChecked = false;
                }
        }
        else
        {
            var simpleList = GroupContext as IEnumerable<IToggableItem>;
            if (simpleList != null)
                foreach (var item in simpleList)
                {
                    if (item != currentItem)
                        item.IsChecked = false;
                }

        }
    }
}

第三步是将GroupContext属性绑定到父ListView的项源。例如:

<ListView x:Name="ParentListView" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" VerticalOptions="Center">
                    <Label Text="{Binding Name}" />
                    <local:GroupedSwitch 
                            IsToggled="{Binding IsChecked}" 
                            GroupContext="{Binding ItemsSource, Source={x:Reference ParentListView}}" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

或者,

<ListView x:Name="_parentList" IsGroupingEnabled="true" >
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <TextCell Text="{Binding Key}" />
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal">
                    <Label Text="{Binding Name}" />
                    <local:GroupedSwitch 
                            ToggledStateFromCode="{Binding IsSwitchOn}" 
                            IsGroupingEnabled="true"
                            GroupContext="{Binding ItemsSource, Source={x:Reference _parentList}}" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

enter image description here

编辑1:更新了代码以添加对分组列表的支持。

答案 1 :(得分:0)

您应该在每台交换机上使用触发器。看看这个:

https://www.tutorialspoint.com/xaml/xaml_triggers.htm