You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义ListView行中绑定Switch与其他控件实现编辑状态切换

问题描述

我有一个自定义ListView,每行包含Label、Entry、Label、Switch、Button。想要实现类似视频中的行编辑效果(切换Switch后,可编辑的Label变为Entry,同时显示保存按钮),但不清楚如何通过Switch实现这种编辑方式。

当前XAML代码:

<ListView
 x:Name="ExpiryProductsData"
 SelectionMode="Single"
 ItemSelected="ExpiryProductsData_ItemSelected"
SeparatorColor="LightGray"
SeparatorVisibility="Default">
<ListView.ItemTemplate>
   <DataTemplate>
        <ViewCell>
           <StackLayout
               Orientation="Horizontal"
               VerticalOptions="Center">
              <Label
                 Text="{Binding Description}"
                 TextColor="Black"
                 VerticalOptions="Center"
                 />
              <Label
                 Text="{Binding DateExpiry}"
                 TextColor="Black"
                 VerticalOptions="Center"
                 />
              <Label
                     Text="{Binding LeftToExpiry}"
                 TextColor="Black"
                    VerticalOptions="Center"
                 />
                 <StackLayout
                     Orientation="Horizontal"
                     HorizontalOptions="EndAndExpand">
                     <Switch
                      x:Name="EditData"
                     Toggled="EditData_Toggled"
                      />
                     </StackLayout>
                   </StackLayout>
               </ViewCell>
            </DataTemplate>
      </ListView.ItemTemplate>
 </ListView>

当前ViewModel代码:

class ViewModel
{
    public string LotNumber { get; set; }
    public string Description { get; set; }
    public string ExpiryDate { get; set; }
    public string LeftToExpiry { get; set; }
}
实现方案

核心思路是通过Switch控制每行的编辑状态,根据状态切换Label(显示模式)和Entry(编辑模式)的可见性,同时显示/隐藏保存按钮。

1. 扩展ViewModel,添加编辑状态属性

给ViewModel增加IsEditing属性标记编辑状态,同时实现INotifyPropertyChanged接口确保UI响应属性变化:

using System.ComponentModel;
using System.Runtime.CompilerServices;

class ViewModel : INotifyPropertyChanged
{
    public string LotNumber { get; set; }
    public string Description { get; set; }
    public string ExpiryDate { get; set; }
    public string LeftToExpiry { get; set; }

    private bool _isEditing;
    public bool IsEditing
    {
        get => _isEditing;
        set
        {
            _isEditing = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 修改XAML布局,实现控件切换

在DataTemplate中,将可编辑的Label替换为Label+Entry组合,通过IsVisible绑定IsEditing控制显示;同时添加保存按钮,根据编辑状态切换可见性:

<ListView
 x:Name="ExpiryProductsData"
 SelectionMode="Single"
 ItemSelected="ExpiryProductsData_ItemSelected"
 SeparatorColor="LightGray"
 SeparatorVisibility="Default">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" VerticalOptions="Center">
                    <!-- 可编辑的Description:Label(非编辑)和Entry(编辑) -->
                    <Label Text="{Binding Description}" 
                           TextColor="Black" 
                           VerticalOptions="Center"
                           IsVisible="{Binding IsEditing, Converter={StaticResource InverseBooleanConverter}}"/>
                    <Entry Text="{Binding Description}" 
                           TextColor="Black" 
                           VerticalOptions="Center"
                           IsVisible="{Binding IsEditing}"
                           WidthRequest="150"/>

                    <!-- ExpiryDate:同样处理 -->
                    <Label Text="{Binding DateExpiry}" 
                           TextColor="Black" 
                           VerticalOptions="Center"
                           IsVisible="{Binding IsEditing, Converter={StaticResource InverseBooleanConverter}}"/>
                    <Entry Text="{Binding DateExpiry}" 
                           TextColor="Black" 
                           VerticalOptions="Center"
                           IsVisible="{Binding IsEditing}"
                           WidthRequest="120"/>

                    <!-- 不可编辑的LeftToExpiry,始终显示Label -->
                    <Label Text="{Binding LeftToExpiry}" 
                           TextColor="Black" 
                           VerticalOptions="Center"/>

                    <StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand">
                        <!-- Switch绑定IsEditing属性 -->
                        <Switch IsToggled="{Binding IsEditing}" />
                        <!-- 保存按钮,仅编辑状态显示 -->
                        <Button Text="保存" 
                                IsVisible="{Binding IsEditing}"
                                Clicked="SaveButton_Clicked"
                                Margin="5,0"/>
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

3. 添加布尔反转转换器

Label需要在非编辑状态显示,因此需要一个InverseBooleanConverter反转IsEditing的值。先在页面资源中注册:

<ContentPage.Resources>
    <ResourceDictionary>
        <local:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
    </ResourceDictionary>
</ContentPage.Resources>

转换器代码:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace YourNamespace
{
    public class InverseBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }
    }
}

4. 处理保存按钮点击事件

在后台代码实现保存逻辑,完成后退出编辑状态:

private void SaveButton_Clicked(object sender, EventArgs e)
{
    var button = sender as Button;
    var viewModel = button.BindingContext as ViewModel;
    
    // 这里添加保存数据的逻辑,比如更新数据库、同步服务器等
    // ...

    // 保存完成后退出编辑状态
    viewModel.IsEditing = false;
}

5. 移除旧的Toggled事件

Switch已直接绑定IsEditing属性,无需再手动处理Toggled事件,可删除XAML中的Toggled="EditData_Toggled"。

内容的提问来源于stack exchange,提问作者Marian34

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:22:50