【问题标题】:Group Swtich Xamarin formsGroup Swtich Xamarin 表单
【发布时间】:2017-09-20 03:14:48
【问题描述】:

我有一个 Listview 可以动态创建数据,并且在每一行中都有一个开关,我想要的是当我切换一个开关时其他的 unggle。 这可以吗?

例子:

<ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.View>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="6*"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Text="{Binding article_description}"
                                   FontAttributes="Bold" FontSize="13"  Margin="10,5,0,-6" Grid.Row="0" LineBreakMode="NoWrap"/>
                        <Label Text="{Binding dish_name}" 
                               FontSize="13" Margin="10,0,0,2" Grid.Row="1" Grid.Column="0"/>
                        <Label Grid.Row="0" Grid.Column="0" x:Name="LabelReserved"  Text="{Binding reserved}" IsVisible="false" LineBreakMode="NoWrap"/> 
                        <Switch Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"  HorizontalOptions="Start" VerticalOptions="Center" IsEnabled="False" Toggled="SwitchMenu_OnToggled" >
                            <Switch.Triggers>
                                <DataTrigger TargetType="Switch" Binding="{Binding Source={x:Reference LabelReserved},
                               Path=Text.Length}" Value="7">
                                    <Setter Property="IsToggled" Value="true" />
                                </DataTrigger>
                            </Switch.Triggers>
                        </Switch>
                    </Grid>
                </ViewCell.View>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>

【问题讨论】:

  • 为什么不将开关绑定到项目视图模型上的 IsToggled 属性,然后在 Switch Toggled 事件中取消除您自己以外的所有开关
  • @user1 我不明白你想让我做什么......

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


【解决方案1】:

注意:这个解决方案是我的一个实验——所以我建议,如果你决定实施它,请谨慎使用。

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

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

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

第二步是扩展Switch 以了解项目列表。我们可以通过添加一个GroupContext 可绑定属性来做到这一点——它基本上代表了父列表视图的ItemsSource

切换开关时,它会遍历项目列表以将其他项目的属性设置为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>

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

【讨论】:

  • 在 foreach 中是 GroupContext 不是 GroupedContext ,对吧?请你去聊天吧。
  • 是的,它是GroupContext。对此感到抱歉。
【解决方案2】:

您应该在每个开关上使用触发器。看看这个:

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

【讨论】:

  • 问题是switch是动态创建的,能举个例子吗?谢谢。
  • “交换机是动态创建的”是什么意思?
  • 哦,我明白你的意思了。
猜你喜欢
  • 2022-11-01
  • 2020-10-04
  • 2019-03-20
  • 2018-01-02
  • 2020-04-28
  • 2021-01-31
  • 2018-03-11
  • 2020-03-09
  • 1970-01-01
相关资源
最近更新 更多