我有一个TableView,用户可以在其中检查多行。 现在我有一个问题,当我选择例如列表中的第5个元素和第5个元素也会被自动检查,但我无法解释原因。
我在TableViewSource基类中使用以下代码:
public abstract class BaseChecklistTableViewSource : UITableViewSource
{
protected int checkCount;
public BaseChecklistTableViewSource()
{
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.CellAt(indexPath);
if (indexPath.Row >= 0)
{
if (cell.Accessory == UITableViewCellAccessory.None)
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
checkCount++;
}
else if (cell.Accessory == UITableViewCellAccessory.Checkmark)
{
cell.Accessory = UITableViewCellAccessory.None;
checkCount--;
}
CheckCheckCount();
}
}
protected void CheckCheckCount()
{
if (checkCount > 0)
{
EnableDoneButton();
}
else if (checkCount == 0)
{
DisableDoneButton();
}
}
protected abstract void EnableDoneButton();
protected abstract void DisableDoneButton();
}
这是“ BaseChecklistTableViewSource”具体类的代码:
public partial class CheckunitTableViewSource : BaseChecklistTableViewSource
{
ListCheckunitController controller;
private IEnumerable<Checkunit> existingCheckunits;
public CheckunitTableViewSource(ListCheckunitController controller)
{
this.controller = controller;
this.existingCheckunits = new List<Checkunit>();
}
public CheckunitTableViewSource(ListCheckunitController controller, IEnumerable<Checkunit> existingCheckunits) : this(controller)
{
if (existingCheckunits == null || !existingCheckunits.Any())
{
throw new ArgumentNullException(nameof(existingCheckunits));
}
this.existingCheckunits = existingCheckunits;
checkCount = this.existingCheckunits.Count();
CheckCheckCount();
}
// Returns the number of rows in each section of the table
public override nint RowsInSection(UITableView tableview, nint section)
{
if (controller.Checkunits == null)
{
return 0;
}
return controller.Checkunits.Count();
}
//
// Returns a table cell for the row indicated by row property of the NSIndexPath
// This method is called multiple times to populate each row of the table.
// The method automatically uses cells that have scrolled off the screen or creates new ones as necessary.
//
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell("checkunitViewCell") ?? new UITableViewCell();
int row = indexPath.Row;
var element = controller.Checkunits.ElementAt(row);
if(existingCheckunits.FirstOrDefault(e => e.Id == element.Id) != null)
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
}
//if(cell.Accessory == UITableViewCellAccessory.Checkmark)
//{
// checkCount++;
//}
cell.TextLabel.Text = $"{element.Order}. {element.Designation}";
cell.Tag = element.Id;
return cell;
}
protected override void EnableDoneButton()
{
controller.EnableDoneButton();
}
protected override void DisableDoneButton()
{
controller.DisableDoneButton();
}
}
我试图在RowSelected方法中使用一个断点,但是该断点只会被击中一次!
这是TableViewController的代码:
public partial class ListCheckunitController : BaseTableViewController
{
private ImmobilePerpetration masterModel;
private LoadingOverlay loadingOverlay;
public IEnumerable<Checkunit> Checkunits { get; set; }
public IEnumerable<Checkunit> existingCheckunits;
public IEnumerable<CheckpointAssessment> existingAssessments;
public static readonly NSString callHistoryCellId = new NSString("checkunitViewCell");
UIRefreshControl refreshControl;
private UIBarButtonItem doneButton;
public ListCheckunitController(IntPtr handle) : base(handle)
{
existingCheckunits = new List<Checkunit>();
existingAssessments = new List<CheckpointAssessment>();
}
public void Initialize(ImmobilePerpetration masterModel)
{
if (masterModel == null)
{
throw new ArgumentNullException(nameof(masterModel));
}
this.masterModel = masterModel;
}
public void Initialize(ImmobilePerpetration masterModel, IEnumerable<CheckpointAssessment> existingAssessments, IEnumerable<Checkunit> existingCheckunits)
{
Initialize(masterModel);
if(existingAssessments == null || !existingAssessments.Any())
{
throw new ArgumentNullException(nameof(existingAssessments));
}
if (existingCheckunits == null || !existingCheckunits.Any())
{
throw new ArgumentNullException(nameof(existingCheckunits));
}
this.existingAssessments = existingAssessments;
this.existingCheckunits = existingCheckunits;
}
async Task RefreshAsync(bool onlineSync)
{
InvokeOnMainThread(() => refreshControl.BeginRefreshing());
try
{
var syncCtrl = new SynchronizationControllerAsync();
Checkunits = await syncCtrl.SynchronizeCheckUnitAsync(onlineSync).ConfigureAwait(false);
}
catch (Exception e)
{
InvokeOnMainThread(() => { AlertHelper.ShowError(e.Message, this);});
}
InvokeOnMainThread(() =>
{
ListCheckunitTable.ReloadData();
refreshControl.EndRefreshing();
});
}
void AddRefreshControl()
{
refreshControl = new UIRefreshControl();
refreshControl.ValueChanged += async (sender, e) =>
{
await RefreshAsync(true).ConfigureAwait(false);
};
}
public override async void ViewDidLoad()
{
var bounds = UIScreen.MainScreen.Bounds;
loadingOverlay = new LoadingOverlay(bounds);
View.Add(loadingOverlay);
AddRefreshControl();
await RefreshAsync(false).ConfigureAwait(false);
InvokeOnMainThread(() =>
{
doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, (s, e) =>
{
PerformSegue("ListCheckpointsSegue", this);
});
doneButton.Enabled = false;
CheckunitTableViewSource source = null;
if(existingCheckunits.Any())
{
source = new CheckunitTableViewSource(this, existingCheckunits);
}
else
{
source = new CheckunitTableViewSource(this);
}
ListCheckunitTable.Source = source;
ListCheckunitTable.Add(refreshControl);
loadingOverlay.Hide();
this.SetToolbarItems(new UIBarButtonItem[] {
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) { Width = 50 }
, doneButton
}, false);
this.NavigationController.ToolbarHidden = false;
});
}
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
{
if (segue.Identifier == "ListCheckpointsSegue")
{
var controller = segue.DestinationViewController as ListCheckpointController;
IList<Checkunit> markedCategories = new List<Checkunit>();
for (int i = 0; i < ListCheckunitTable.NumberOfRowsInSection(0); i++)
{
var cell = ListCheckunitTable.CellAt(NSIndexPath.FromItemSection(i, 0));
if(cell != null)
{
if(cell.Accessory == UITableViewCellAccessory.Checkmark)
{
var originalObject = Checkunits.Where(e => e.Id == cell.Tag).SingleOrDefault();
if(originalObject != null)
{
markedCategories.Add(originalObject);
}
else
{
//TODO: Handle error case!
}
}
}
}
if (markedCategories.Any())
{
if (controller != null)
{
if(existingAssessments.Any() && existingCheckunits.Any())
{
controller.Initialize(masterModel, markedCategories, existingAssessments, existingCheckunits);
}
else
{
controller.Initialize(masterModel, markedCategories);
}
}
}
else
{
//TODO: Print out message, that there are no marked elements!
}
}
}
public void DisableDoneButton()
{
doneButton.Enabled = false;
}
public void EnableDoneButton()
{
doneButton.Enabled = true;
}
}
使用的基类仅处理公共侧边栏视图。 有人知道这里出了什么问题吗?
答案 0 :(得分:0)
好吧,我最终创建了一个bool Array,用于存储选中的元素。 我尝试了来自Xamarin的Github的演示应用程序,但我遇到了完全相同的问题。 这使我得出结论,认为这一定是Xamarin Bug!