如何在为所选项目添加复选标记后更新 table 视图?
How to update table view after adding checkmark to selected item?
我正在 Xamarin MvvmCross 项目中的 iOS 视图中创建清单。一切正常,除了在选择项目时显示复选标记并在取消选择项目时移除复选标记。
我控制器的 ViewDidLoad 内部:
var source = new EntryTypesTableSource(eventsDialogTable, EntryTypeCell.Key, EntryTypeCell.Key);
eventsDialogTable.Source = source;
var set = this.CreateBindingSet<EventsDialogView,EventsDialogViewModel>();
set.Bind(source).To(vm => vm.SelectedItem.EntryTypes);
set.Apply();
我尝试调用 ReloadData 但数据没有改变,只有 UI 改变了,我也尝试在 GetCell 中设置复选标记但与 RowSelected
中的问题相同
以及 table 来源的代码:
public class EntryTypesTableSource : MvxSimpleTableViewSource
{
NSIndexPath selectedBefore;
public EntryTypesTableSource(UITableView tableView, string nibName, string cellIdentifier = null, NSBundle bundle = null) : base(tableView, nibName, cellIdentifier, bundle)
{
tableView.AllowsMultipleSelection = false;
tableView.AllowsSelection = true;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = base.GetCell(tableView, indexPath);
//Default first item is selected
if (indexPath.Row == 0 )
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
selectedBefore = indexPath;
}
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
base.RowSelected(tableView, indexPath);
if (indexPath != null)
{
UITableViewCell cellNow = tableView.CellAt(indexPath);//currently selected
UITableViewCell cellOld = tableView.CellAt(selectedBefore); //previous
if (selectedBefore != indexPath)
{
cellOld.Accessory = UITableViewCellAccessory.None;
tableView.DeselectRow(selectedBefore, true);
cellNow.Accessory = UITableViewCellAccessory.Checkmark;
selectedBefore = indexPath;
tableView.EndUpdates();
}
}
}
}
控制器代码:
public partial class EventsDialogView : MvxViewController<EventsDialogViewModel>
{
public EventsDialogView()
{
}
public override void ViewDidLoad()
{
// Releases the view if it doesn't have a superview.
base.ViewDidLoad();
//values
var dialogWidth = 0.8 * this.View.Frame.Width;
//float headerHeight = 50f;
//float footerHeight = 50f;
float rowHeight = 50f;
int numberOfRows = selectedItem.EntryTypes.Count + 2;//+2 for header and footer
float tableHeigth = numberOfRows * rowHeight;
//table
var eventsDialogTable = new UITableView();
eventsDialogTable.Frame = new CoreGraphics.CGRect((this.View.Frame.Width - dialogWidth) / 2, (this.View.Frame.Height - tableHeigth) / 2, dialogWidth, tableHeigth);
this.View.AddSubview(eventsDialogTable);
var source = new EntryTypesTableSource(eventsDialogTable);
eventsDialogTable.Source = source;
eventsDialogTable.SeparatorStyle = UITableViewCellSeparatorStyle.None;
/*Binding*/
var set = this.CreateBindingSet<EventsDialogView,EventsDialogViewModel>();
set.Bind(source).To(vm => vm.SelectedItem.EntryTypes);
set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.EntrySelected);
set.Apply();
}
}
视图模型:
public class EventsDialogViewModel : MvxViewModel
{
private ObservableCollection<EntryType> entryTypeCollection = new ObservableCollection<EntryType>();
private Device selectedItem;
private EntryType selectedEntry;
public EventsDialogViewModel(){}
public ObservableCollection<EntryType>EntryTypeCollection
{
get { return entryTypeCollection; }
set
{
entryTypeCollection = value;
RaisePropertyChanged(() => EntryTypeCollection);
}
}
public Device SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
RaisePropertyChanged(() => SelectedItem);
}
}
public EntryType SelectedEntry
{
get { return selectedEntry; }
set
{
selectedEntry = value;
RaisePropertyChanged(() => SelectedEntry);
}
}
}
绑定工作正常,我可以捕获 clicked/selected 项目,但视图没有更新(我使用 xcode 模拟器)。欢迎任何建议!
您可以尝试将您的 TableSource 代码与此交换:
public class EntryTypesTableSource : MvxTableViewSource
{
private bool _isFirst = true;
private NSIndexPath _previousSelectedRow = null;
public HomeTableViewSource(UITableView tableView) : base(tableView)
{
tableView.RegisterNibForCellReuse(EntryTypeCell.Nib, EntryTypeCell.Key);
tableView.AllowsMultipleSelection = false;
tableView.AllowsSelection = true;
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
var cell = tableView.DequeueReusableCell(EntryTypeCell.Key, indexPath);
if (_isFirst)
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
_previousSelectedRow = indexPath;
_isFirst = false;
}
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if (_previousSelectedRow == indexPath)
return;
base.RowSelected(tableView, indexPath);
var cell = tableView.CellAt(indexPath);
cell.Accessory = UITableViewCellAccessory.Checkmark;
var previousSelectedCell = tableView.CellAt(_previousSelectedRow);
previousSelectedCell.Accessory = UITableViewCellAccessory.None;
_previousSelectedRow = indexPath;
}
}
然后在你的视图控制器中你应该更新
var source = new EntryTypesTableSource(eventsDialogTable, EntryTypeCell.Key, EntryTypeCell.Key);
进入
var source = new EntryTypesTableSource(eventsDialogTable);
您还可以尝试将 RowSelected
方法更新为:
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if (_previousSelectedRow == indexPath)
return;
base.RowSelected(tableView, indexPath);
var cell = tableView.CellAt(indexPath);
var previousSelectedCell = tableView.CellAt(_previousSelectedRow);
InvokeOnMainThread(() =>
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
previousSelectedCell.Accessory = UITableViewCellAccessory.None;
});
_previousSelectedRow = indexPath;
}
我在设备上 运行 应用后一切正常。这是模拟器问题。我保留了我的代码的原始版本。感谢大家的帮助和时间
我正在 Xamarin MvvmCross 项目中的 iOS 视图中创建清单。一切正常,除了在选择项目时显示复选标记并在取消选择项目时移除复选标记。
我控制器的 ViewDidLoad 内部:
var source = new EntryTypesTableSource(eventsDialogTable, EntryTypeCell.Key, EntryTypeCell.Key);
eventsDialogTable.Source = source;
var set = this.CreateBindingSet<EventsDialogView,EventsDialogViewModel>();
set.Bind(source).To(vm => vm.SelectedItem.EntryTypes);
set.Apply();
我尝试调用 ReloadData 但数据没有改变,只有 UI 改变了,我也尝试在 GetCell 中设置复选标记但与 RowSelected
中的问题相同以及 table 来源的代码:
public class EntryTypesTableSource : MvxSimpleTableViewSource
{
NSIndexPath selectedBefore;
public EntryTypesTableSource(UITableView tableView, string nibName, string cellIdentifier = null, NSBundle bundle = null) : base(tableView, nibName, cellIdentifier, bundle)
{
tableView.AllowsMultipleSelection = false;
tableView.AllowsSelection = true;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = base.GetCell(tableView, indexPath);
//Default first item is selected
if (indexPath.Row == 0 )
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
selectedBefore = indexPath;
}
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
base.RowSelected(tableView, indexPath);
if (indexPath != null)
{
UITableViewCell cellNow = tableView.CellAt(indexPath);//currently selected
UITableViewCell cellOld = tableView.CellAt(selectedBefore); //previous
if (selectedBefore != indexPath)
{
cellOld.Accessory = UITableViewCellAccessory.None;
tableView.DeselectRow(selectedBefore, true);
cellNow.Accessory = UITableViewCellAccessory.Checkmark;
selectedBefore = indexPath;
tableView.EndUpdates();
}
}
}
}
控制器代码:
public partial class EventsDialogView : MvxViewController<EventsDialogViewModel>
{
public EventsDialogView()
{
}
public override void ViewDidLoad()
{
// Releases the view if it doesn't have a superview.
base.ViewDidLoad();
//values
var dialogWidth = 0.8 * this.View.Frame.Width;
//float headerHeight = 50f;
//float footerHeight = 50f;
float rowHeight = 50f;
int numberOfRows = selectedItem.EntryTypes.Count + 2;//+2 for header and footer
float tableHeigth = numberOfRows * rowHeight;
//table
var eventsDialogTable = new UITableView();
eventsDialogTable.Frame = new CoreGraphics.CGRect((this.View.Frame.Width - dialogWidth) / 2, (this.View.Frame.Height - tableHeigth) / 2, dialogWidth, tableHeigth);
this.View.AddSubview(eventsDialogTable);
var source = new EntryTypesTableSource(eventsDialogTable);
eventsDialogTable.Source = source;
eventsDialogTable.SeparatorStyle = UITableViewCellSeparatorStyle.None;
/*Binding*/
var set = this.CreateBindingSet<EventsDialogView,EventsDialogViewModel>();
set.Bind(source).To(vm => vm.SelectedItem.EntryTypes);
set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.EntrySelected);
set.Apply();
}
}
视图模型:
public class EventsDialogViewModel : MvxViewModel
{
private ObservableCollection<EntryType> entryTypeCollection = new ObservableCollection<EntryType>();
private Device selectedItem;
private EntryType selectedEntry;
public EventsDialogViewModel(){}
public ObservableCollection<EntryType>EntryTypeCollection
{
get { return entryTypeCollection; }
set
{
entryTypeCollection = value;
RaisePropertyChanged(() => EntryTypeCollection);
}
}
public Device SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
RaisePropertyChanged(() => SelectedItem);
}
}
public EntryType SelectedEntry
{
get { return selectedEntry; }
set
{
selectedEntry = value;
RaisePropertyChanged(() => SelectedEntry);
}
}
}
绑定工作正常,我可以捕获 clicked/selected 项目,但视图没有更新(我使用 xcode 模拟器)。欢迎任何建议!
您可以尝试将您的 TableSource 代码与此交换:
public class EntryTypesTableSource : MvxTableViewSource
{
private bool _isFirst = true;
private NSIndexPath _previousSelectedRow = null;
public HomeTableViewSource(UITableView tableView) : base(tableView)
{
tableView.RegisterNibForCellReuse(EntryTypeCell.Nib, EntryTypeCell.Key);
tableView.AllowsMultipleSelection = false;
tableView.AllowsSelection = true;
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
var cell = tableView.DequeueReusableCell(EntryTypeCell.Key, indexPath);
if (_isFirst)
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
_previousSelectedRow = indexPath;
_isFirst = false;
}
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if (_previousSelectedRow == indexPath)
return;
base.RowSelected(tableView, indexPath);
var cell = tableView.CellAt(indexPath);
cell.Accessory = UITableViewCellAccessory.Checkmark;
var previousSelectedCell = tableView.CellAt(_previousSelectedRow);
previousSelectedCell.Accessory = UITableViewCellAccessory.None;
_previousSelectedRow = indexPath;
}
}
然后在你的视图控制器中你应该更新
var source = new EntryTypesTableSource(eventsDialogTable, EntryTypeCell.Key, EntryTypeCell.Key);
进入
var source = new EntryTypesTableSource(eventsDialogTable);
您还可以尝试将 RowSelected
方法更新为:
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if (_previousSelectedRow == indexPath)
return;
base.RowSelected(tableView, indexPath);
var cell = tableView.CellAt(indexPath);
var previousSelectedCell = tableView.CellAt(_previousSelectedRow);
InvokeOnMainThread(() =>
{
cell.Accessory = UITableViewCellAccessory.Checkmark;
previousSelectedCell.Accessory = UITableViewCellAccessory.None;
});
_previousSelectedRow = indexPath;
}
我在设备上 运行 应用后一切正常。这是模拟器问题。我保留了我的代码的原始版本。感谢大家的帮助和时间