【发布时间】:2022-10-02 04:39:07
【问题描述】:
我有一个 ObeservableCollection 用作列表视图的数据绑定。以下是列表的示例:
[{\"Category\":\"ENGINE\",\"Key\":\"BATTERY\",\"Value\":\"BATTERY\"},
{\"Category\":\"BRAKE\",\"Key\":\"BRAKE\",\"Value\":\"BRAKE PAD\"},
{\"Category\":\"ENGINE\",\"Key\":\"COOLANT\",\"Value\":\"COOLANT & WATER\"}]
我已经实现的类似于以下屏幕截图:
列表显示
是的,我可以使用组描述符根据模型中的一个属性对它们进行分组,并使用右侧的复选框将数据模板分配给 GroupHeaderTemplate。
但是,问题是我无法通过调用 id 或 name 来访问组复选框,因为它是动态创建的。
我的要求是将组(黑色)和子项(粉红色)复选框链接在一起,这意味着当所有属于该组的子项都已被选中时,组复选框也应自动选中,反之亦然。一旦取消选择其中一项,则组复选框也应取消选择。
目前卡住了,不知道如何进行,任何帮助将不胜感激。谢谢~
用代码编辑:GroupedCheckList.xaml
<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<ContentPage
xmlns=\"http://xamarin.com/schemas/2014/forms\"
xmlns:syncfusion=\"clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms\"
xmlns:data=\"clr-namespace:Syncfusion.DataSource;assembly=Syncfusion.DataSource.Portable\"
xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\" xmlns:local=\"clr-namespace:ASolute_Mobile\" xmlns:local1=\"clr-namespace:ASolute_Mobile.Models.GroupedCheckListModel\" xmlns:button=\"clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms\"
x:Class=\"ASolute_Mobile.FleetScreen.GroupedCheckList\">
<StackLayout x:Name=\"Fleet_CheckItem\" Spacing=\"15\" Padding=\"15,15,15,15\">
<syncfusion:SfListView x:Name=\"groupedListView\" ItemsSource=\"{Binding Check}\" AllowGroupExpandCollapse=\"True\">
<syncfusion:SfListView.DataSource>
<data:DataSource>
<data:DataSource.GroupDescriptors>
<data:GroupDescriptor PropertyName=\"Category\">
</data:GroupDescriptor>
</data:DataSource.GroupDescriptors>
</data:DataSource>
</syncfusion:SfListView.DataSource>
<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<StackLayout>
<button:SfCheckBox Text=\"{Binding Name}\" IsChecked=\"{Binding IsSelected}\" CheckedColor=\"LightCoral\" FontSize=\"20\" StateChanged=\"CheckBox_StateChanged\" />
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
</syncfusion:SfListView>
<Image Source=\"nextPage.png\" WidthRequest=\"70\" HeightRequest=\"70\" VerticalOptions=\"Center\" HorizontalOptions=\"End\" x:Name=\"fleet_confirm_icon\" IsVisible=\"false\">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped=\"fleet_toNextPage\" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</ContentPage>
GroupedCheckList.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using ASolute.Mobile.Models;
using ASolute_Mobile.Models;
using ASolute_Mobile.Models.GroupedCheckListModel;
using ASolute_Mobile.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Syncfusion.XForms.Buttons;
using Xamarin.Forms;
namespace ASolute_Mobile.FleetScreen
{
public partial class GroupedCheckList : ContentPage
{
private ListItems item;
string recordURL;
List<clsCheckListItem> checkItems = new
List<clsCheckListItem>();
bool shouldLeave = true;
public GroupedCheckList()
{
InitializeComponent();
shouldLeave = false;
StackLayout main = new StackLayout();
Label title1 = new Label
{
FontSize = 15,
Text = \"Check List\",
TextColor = System.Drawing.Color.White
};
Label title2 = new Label
{
FontSize = 10,
Text = Ultis.Settings.SubTitle,
TextColor = System.Drawing.Color.White
};
main.Children.Add(title1);
main.Children.Add(title2);
NavigationPage.SetTitleView(this, main);
NavigationPage.SetHasBackButton(this, false);
displayData();
}
public GroupedCheckList(ListItems items, string recordUri)
{
item = items;
InitializeComponent();
shouldLeave = true;
recordURL = recordUri;
StackLayout main = new StackLayout();
Label title1 = new Label
{
FontSize = 15,
Text = \"Check List\",
TextColor = System.Drawing.Color.White
};
Label title2 = new Label
{
FontSize = 10,
Text = Ultis.Settings.SubTitle,
TextColor = System.Drawing.Color.White
};
main.Children.Add(title1);
main.Children.Add(title2);
NavigationPage.SetTitleView(this, main);
GetData();
}
async void GetData()
{
try
{
var content = await DependencyService.Get<CommonFunctionInterface>().CallWebService(0, null, Ultis.Settings.SessionBaseURI, recordURL, this);
if (content != null)
{
clsResponse response = JsonConvert.DeserializeObject<clsResponse>(content);
if (response.Result != \"\")
{
var msgBoxResponse = await DisplayAlert(\"Info\", response.Result, \"YES\", \"NO\");
if (msgBoxResponse)
{
displayData();
}
else
{
await Navigation.PopAsync();
}
}
else
{
displayData();
}
}
}
catch (Exception e)
{
await DisplayAlert(\"Error\", e.Message, \"OK\");
}
}
async void displayData()
{
try
{
var content1 = await DependencyService.Get<CommonFunctionInterface>().CallWebService(0, null, Ultis.Settings.SessionBaseURI, ControllerUtil.getNewFleetCheckListURL(), this);
if (content1 != null)
{
clsResponse response1 = JsonConvert.DeserializeObject<clsResponse>(content1);
if (response1.IsGood == true)
{
checkItems = JObject.Parse(content1)[\"Result\"].ToObject<List<clsCheckListItem>>();
BindingContext = new GroupedCheckListModel(checkItems);
groupedListView.GroupHeaderTemplate = new DataTemplate(() => {
StackLayout headerStack = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand
};
StackLayout labelStack = new StackLayout
{
HorizontalOptions = LayoutOptions.StartAndExpand,
};
Label label = new Label()
{
FontSize = 22,
FontAttributes = FontAttributes.Bold
};
//Key is the property group.Key, not from our list
label.SetBinding(Label.TextProperty, \"Key\");
labelStack.Children.Add(label);
StackLayout checkBoxStack = new StackLayout
{
HorizontalOptions = LayoutOptions.EndAndExpand
};
SfCheckBox checkBox = new SfCheckBox();
checkBox.SetBinding(SfCheckBox.IsCheckedProperty, \"IsSelected\");
checkBox.StateChanged += SfCheckBox_StateChanged;
checkBoxStack.Children.Add(checkBox);
headerStack.Children.Add(labelStack);
headerStack.Children.Add(checkBoxStack);
return new ViewCell { View = headerStack, StyleId = \"NewViewCell\" };
});
//groupedListView.DataSource.GroupDescriptors.Add(new Syncfusion.DataSource.GroupDescriptor()
//{
// PropertyName = \"Category\",
// KeySelector = (object obj1) =>
// {
// var item = (obj1 as GroupCheckListItem);
// return item.Category[0].ToString();
// }
//});
}
fleet_confirm_icon.IsVisible = true;
}
}
catch (Exception e)
{
await DisplayAlert(\"Error\", e.Message, \"OK\");
}
}
async void CheckBox_StateChanged(System.Object sender, Syncfusion.XForms.Buttons.StateChangedEventArgs e)
{
}
public async void fleet_toNextPage(object sender, EventArgs e)
{
checkItems.Clear();
try
{
//if (fleet_selectAll.IsChecked == true)
//{
// checkItems.Clear();
//}
//else
//{
ObservableCollection<GroupedCheckListItem> checkedItems = new ObservableCollection<GroupedCheckListItem>();
checkedItems = GroupedCheckListModel.CheckedList;
foreach (GroupedCheckListItem item1 in checkedItems)
{
if (item1.IsSelected == false)
{
//checkItems.Add(new clsCheckListItem(item1.Category, item1.Name));
}
}
//}
var content = await DependencyService.Get<CommonFunctionInterface>().CallWebService(0, null, Ultis.Settings.SessionBaseURI, ControllerUtil.getDownloadMenuURL(), this);
clsResponse response = JsonConvert.DeserializeObject<clsResponse>(content);
if (response.IsGood == true)
{
var menu = JObject.Parse(content)[\"Result\"].ToObject<clsLogin>();
//await Navigation.PushAsync(new CheckList2(checkItems, menu.CheckListLinkId));
}
}
catch (Exception exception)
{
await DisplayAlert(\"Error\", exception.Message, \"Ok\");
}
}
async void SfCheckBox_StateChanged(System.Object sender, Syncfusion.XForms.Buttons.StateChangedEventArgs e)
{
try
{
SfCheckBox checkBox = sender as SfCheckBox;
var binding = checkBox.BindingContext as Syncfusion.DataSource.Extensions.GroupResult;
var groupedList = checkItems.GroupBy(x => x.Category);
foreach (var group in groupedList)
{
if (group.Key == binding.Key.ToString())
{
ObservableCollection<GroupedCheckListItem> oriItems = new ObservableCollection<GroupedCheckListItem>();
oriItems = GroupedCheckListModel.CheckedList;
foreach (var item in oriItems)
{
if (item.Category == group.Key)
{
item.IsSelected = checkBox.IsChecked.Value ? true : false;
}
}
break;
}
}
}
catch (Exception ex)
{
await DisplayAlert(\"Error\", ex.Message, \"Ok\");
}
}
}
}
GroupedCheckListModel.cs
using ASolute.Mobile.Models;
using ASolute_Mobile.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using Xamarin.Forms;
namespace ASolute_Mobile.Models.GroupedCheckListModel
{
public class GroupedCheckListModel : PropertyChange
{
public static ObservableCollection<GroupedCheckListItem> chkList;
public ObservableCollection<GroupedCheckListItem> Check
{
set { SetProperty(ref chkList, value); }
get { return chkList; }
}
public GroupedCheckListModel(List<clsCheckListItem> listItems)
{
Check = new ObservableCollection<GroupedCheckListItem>();
foreach (clsCheckListItem item in listItems)
{
Check.Add(AddNew(item.Category, item.Key, item.Value, false));
};
}
public static ObservableCollection<GroupedCheckListItem> CheckedList
{
get { return chkList; }
}
private GroupedCheckListItem AddNew(string category, string key, string value, bool isSelected)
{
var chkItem = new GroupedCheckListItem(category, key, value, isSelected);
return chkItem;
}
}
public class GroupingSelectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return value;
return value;
//GroupResult groupResult = value as GroupResult;
//SfListView listview = parameter as SfListView;
//var items = new List<MusicInfo>(groupResult.Items.ToList<MusicInfo>());
//if ((items.All(listitem => listitem.IsSelected == false)))
//{
// for (int i = 0; i < items.Count(); i++)
// {
// var item = items[i];
// (item as MusicInfo).IsSelected = false;
// listview.SelectedItems.Remove(item);
// }
// return ImageSource.FromResource(\"CustomSelection.Images.NotSelected.png\");
//}
//else if ((items.All(listitem => listitem.IsSelected == true)))
//{
// for (int i = 0; i < items.Count(); i++)
// {
// var item = items[i];
// (item as MusicInfo).IsSelected = true;
// listview.SelectedItems.Add(item);
// }
// return ImageSource.FromResource(\"CustomSelection.Images.Selected.png\");
//}
//else
// return ImageSource.FromResource(\"CustomSelection.Images.Intermediate.png\");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class SelectionBoolToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//if ((bool)value)
// return ImageSource.FromResource(\"CustomSelection.Images.Selected.png\");
//else
// return ImageSource.FromResource(\"CustomSelection.Images.NotSelected.png\");
if (value == null)
return value;
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
分组检查列表项
using System;
namespace ASolute_Mobile.Models.GroupedCheckListModel
{
public class GroupedCheckListItem : PropertyChange
{
private string category;
private string name;
private string key;
private bool isSelected;
public string Category
{
set { SetProperty(ref category, value); }
get { return category; }
}
public string Name
{
set { SetProperty(ref name, value); }
get { return name; }
}
public string Key
{
set { SetProperty(ref key, value); }
get { return key; }
}
public bool IsSelected
{
set { SetProperty(ref isSelected, value); }
get { return isSelected; }
}
public GroupedCheckListItem(string category, string key, string name, bool isSelected)
{
Category = category;
Key = key;
Name = name;
IsSelected = isSelected;
}
}
}
-
如果您不向我们展示您的代码,我们将无法帮助您修复您的代码
-
谢谢你提醒杰森。我已经编辑了我的问题,请再看看。
标签: xamarin syncfusion