如何在使用Xamarin表单选中复选框时显示对象

dy1byipe  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(144)

当用户选中网格中的复选框时,如何显示对象?数据在网格中的集合视图中。处理按钮也在下面的网格中。即使我使用MVVM也可以做到吗?
例如,他们选择了任何:

当没有选择项目时,“处理”按钮将显示和隐藏。下面是XAML

<StackLayout >
    <!--<SearchBar Placeholder="Search..."/>-->
    <RefreshView   x:DataType="local:ShpAgentMainPageViewModel"  Command="{Binding LoadReleaseDocumentsSA}" 
                       IsRefreshing="{Binding IsRefreshing ,Mode=OneWay}" RefreshColor="#FFFF7F50">
        <CollectionView   x:Name="DeliveredList" 
                    ItemsSource="{Binding DeliveredDocuments}"
                    SelectionMode="None" >
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout   Padding="3" x:DataType="model:Deliver"> 
                        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                            ...
                        </Grid> 
                    </StackLayout> 
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </RefreshView>
    <Grid x:Name="BelowMenu">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button 
            CornerRadius="5"
            Grid.Row="0" 
            Text="PROCESS"  
            FontAttributes="Bold" 
            BackgroundColor="#FF7F50" 
            TextColor="White"  
            WidthRequest="100" 
            HeightRequest="70" 
            Margin="20,0,20,22" 
            HorizontalOptions="End" 
            VerticalOptions="End" 
            Command="{Binding TMPendingDetailsPageShpAgent}"        
            />   
    </Grid>
</StackLayout>

对于我的ViewModel:

public class ShpAgentMainPageViewModel : BaseViewModel
{
    public Command<Deliver> TMPendingDetailsPageShpAgent { get; set; }
    public ShpAgentMainPageViewModel()
    {
        try
        {
             
            TMPendingDetailsPageShpAgent = new Command<Deliver>(OnTMPendingTransferPageShpAgentTap);
 
        }
        catch(Exception ex)
        {
            Debug.WriteLine(ex);

            Debug.WriteLine(ex.ToString()); 
        }
    }

    async void OnTMPendingTransferPageShpAgentTap(Deliver Book)
    {
        IEnumerable<String> selectedData = DeliveredDocuments.Where(d => d.IsSelected).Select(d => d.TMNo).ToArray();
        if (selectedData.Count() == 0)
            return;

        string tmNo = string.Join("|", selectedData);

        try
        {
            ...
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString()); 
        }
  
    }   
}
v7pvogib

v7pvogib1#

由于我们无法看到您项目的其他详细代码(如Deliver),但您可以参考以下实现类似功能的代码。
MeetAWalkerViewModel.cs

public class MeetAWalkerViewModel: INotifyPropertyChanged
{
    public ObservableCollection<PetProfile> source;
    //public ObservableCollection<PetProfile> PetInfo { get; private set; }
    public ObservableCollection<PetProfile> EmptyPetInfo
    {
        get => source;
        private set
        {
            if (value != source)
            {
                source = value;
                OnPropertyChanged(nameof(EmptyPetInfo));
            }
        }
    }

    int _count;
    public int Count
    {
        set
        {
            if (_count != value)
            {
                _count = value;
                OnPropertyChanged(nameof(Count));

                Sel = "Amount of selected pets is : " + Convert.ToString(_count);
            }
        }
        get
        {
            return _count;
        }
    }

    public void updateCount(int count) { 
    
    }

    String sel;
    public String Sel
    {
        set
        {
            if (sel != value)
            {
                sel = value;
                OnPropertyChanged(nameof(Sel));
            }
        }
        get
        {
            return sel;
        }
    }

    public MeetAWalkerViewModel()
    {
        EmptyPetInfo = new ObservableCollection<PetProfile>();
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet1", IsSelected= false,ImageUrl= "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet2", IsSelected = false, ImageUrl = "watermelon.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet3", IsSelected = false, ImageUrl = "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet4", IsSelected = false, ImageUrl = "watermelon.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet5", IsSelected = false, ImageUrl = "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet6", IsSelected = false, ImageUrl = "watermelon.png" });

        foreach (PetProfile petProfile in EmptyPetInfo) {
            if (petProfile.IsSelected)
            {
                Count++;
            }

        }
        Sel = "Amount of selected pets is : " + Convert.ToString(Count);
    }

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

MainPage.xaml

<StackLayout HorizontalOptions="Center"  Padding="10" >
    <Label   x:Name="countSelectedItemsLabel" Text="{Binding Sel}" FontSize="20" />

    <CollectionView  x:Name="petCollectionView"  ItemsSource="{Binding EmptyPetInfo}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10" RowDefinitions="80" ColumnDefinitions="120,60,60">
                    <Image Grid.Column="0"
                            Grid.Row="0"
                            x:Name="PetImage"
                            Source="{Binding ImageUrl}"/>
                    <Label Grid.Column="1"
                            Grid.Row="0"
                            Text="{Binding PetName}"
                            FontAttributes="Bold"
                            x:Name="labelpetname" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                    <CheckBox  Grid.Row="0" Grid.Column="2" HorizontalOptions="End" IsChecked="{Binding IsSelected, Mode=TwoWay}" CheckedChanged="CheckBox_CheckedChanged" BindingContext="{Binding .}"/>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

MainPage.xaml.cs

public partial class MainPage : ContentPage
{

    MeetAWalkerViewModel viewModel;

    int selectedCount = 0;

    public MainPage()
    {
        InitializeComponent();

        viewModel = new MeetAWalkerViewModel();
        BindingContext = viewModel;
    }

    private void CheckBox_CheckedChanged(object sender, CheckedChangedEventArgs e)
    {
        PetProfile model = (PetProfile)((CheckBox)sender).BindingContext;

        if (model.IsSelected)
        {
            selectedCount++;
        }
        else
        {
            selectedCount--;
        }

        viewModel.Count = selectedCount;

    }
}

PetProfile.cs

public class PetProfile
{
    public string PetName { get; set; }

    public string ImageUrl { get; set; }

    public bool IsSelected { get; set; }
}

如需详细信息,您可以检查thread:Count selected checkboxes in collectionview xamarin

0yycz8jy

0yycz8jy2#

Sure it can be done.
In Xamarin MVVM you should use bindings for things like these. You can use these in a few variations:

  1. Bind directly to another element (or its member) in the view
  2. Bind to a value in the view model (typical usage)
  3. Bind to the result of a converter (to change the type of a binded value)
  4. Markup extensions (can be used to convert the type of value defined in xaml)
    For your use case you have two options:
  • a combination of (1) and (3):

Set SelectionMode="Multiple" to use the built in selection mechanics of the CollectionView . CollectionView has a property SelectedItems , see: doc . Bind the IsVisible property of the process button to the CollectionView 's SelectedItems . Linking to the right object is the difficult part. Use the Source property on the binding, to make sure it looks for the object in the right place (view, and not view model). Pay attention to the debug messages at runtime, these will tell you when a binding is failing.
Then do the type conversion with a IsNotEmptyConverter . This takes your List , does something like return list.Count > 0 .

  • a combination of (2) and (3): Ditch the CollectionView if you're not using the built-in mechanics for selection. StackLayout with ItemSource is the most simple option. Bind the IsVisible property of the process button to your viewmodel's DeliveredDocuments . Then write a AnyDocumentIsSelected converter that takes a List<DeliveredDocuments> and returns true if any of them have a IsSelected that is true .

相关问题