提问人:Craig85 提问时间:9/29/2023 最后编辑:Craig85 更新时间:9/29/2023 访问量:27
ListView 在 Xamarin Forms 中的模式页面操作后未更新
ListView not updating after modal page actions in Xamarin Forms
问:
我正在 Xamarin Forms 中创建应用程序。我有一个带有单个 ListViews 的 TabbedPage 来显示和处理坐标和点。为了添加/更新项目,我创建了一个 ToolBarItem。这会在单独的页面上弹出一个模式。此模式具有带有取消(基本上关闭)或提交更改的按钮的输入字段。同样将用于修改现有坐标/点。 我有一个 viewModel(假设是主 viewModel),它有 ObservableCollection 来填充列表视图数据,它实现了 INotifyPropertyChanged 并从 BindableObject 派生:
public class DataViewModel : **BindableObject**, **INotifyPropertyChanged**
{
private DataStoreManager dataStoreManager;
public ObservableCollection<DataItem> Coordinates { get; set; }
public ObservableCollection<DataItem> Points { get; set; }
public DataViewModel()
{
LoadItems();
}
internal void LoadItems()
{
dataStoreManager = DataStoreManager.GetInstance();
this.Coordinates = new ObservableCollection<DataItem>(dataStoreManager.GetAll<DataItem>(DataType.Coordinate));
this.Points = new ObservableCollection<DataItem>(dataStoreManager.GetAll<DataItem>(DataType.Point));
}
public ICommand DeleteCommand => new Command<DataItem>((DataItem item) =>
{
dataStoreManager.RemoveItem<DataItem>(item);
if (item.Type == DataType.Coordinate)
{
Coordinates.Remove(item);
OnPropertyChanged(nameof(Coordinates));
}
else if (item.Type == DataType.Point)
{
Points.Remove(item);
OnPropertyChanged(nameof(Points));
}
});
}
此视图模型当前仅处理删除操作。 xaml 代码如下所示:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:Test.ViewModels"
x:Class="Test.Views.DataTabbedPage">
<TabbedPage.ToolbarItems>
<ToolbarItem Text="New" Order="Primary" Priority="0" Clicked="OnNewButtonClicked" IconImageSource="baseline_note_add_24.xml"></ToolbarItem>
</TabbedPage.ToolbarItems>
<ContentPage Title="Coordinates" x:Name="coordinatesPage">
<ContentPage.BindingContext>
<viewmodels:DataViewModel />
</ContentPage.BindingContext>
<Grid>
<ListView ItemsSource="{Binding Path=Coordinates}" CachingStrategy="RecycleElement" x:Name="coordinatesListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="20, 15, 20, 0" HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" Grid.Column="0" />
<Label Text="{Binding Value}" Grid.Column="1" />
</Grid>
<ViewCell.ContextActions>
<MenuItem Text="Modify" Clicked="OnEditButtonClicked" CommandParameter="{Binding .}"/>
<MenuItem Text="Remove" Command="{Binding Source={x:Reference coordinatesPage}, Path=BindingContext.DeleteCommand}" CommandParameter="{Binding .}" />
</ViewCell.ContextActions>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ContentPage>
...
</TabbedPage>
模态页面的 viewmodel 派生自它,这就是 dataEditViewModel。它应该处理更新和新操作:
public class DataEditViewModel : DataViewModel, INotifyPropertyChanged
{
private DataStoreManager dataStoreManager;
public DataItem Item { get; set; } = new DataItem();
public bool IsNewAction { get; internal set; }
public bool IsEditAction { get; internal set; }
public DataEditViewModel()
{
this.OnPropertyChanged(nameof(this.Item));
this.dataStoreManager = DataStoreManager.GetInstance();
}
public ICommand NewCommand => new Command<DataItem>((DataItem item) =>
{
item.Type = DataType.Coordinate;
dataStoreManager.AddItem(item);
Device.BeginInvokeOnMainThread(() =>
{
Coordinates.Add(item);
OnPropertyChanged(nameof(Coordinates));
});
});
public ICommand CommitCommand => new Command<DataItem>((DataItem item) =>
{
dataStoreManager.UpdateItem(item);
DataItem itemToRemove = Coordinates.Single(i => i.Id == item.Id);
Coordinates.Remove(itemToRemove);
Coordinates.Add(item);
OnPropertyChanged(nameof(Coordinates));
});
}
此模式的 xaml 如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:Test.ViewModels"
x:Class="Test.Views.DataEditPage"
x:Name="dataEditPage"
Title="Edit Data">
<ContentPage.BindingContext>
<viewmodels:DataEditViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<Entry x:Name="NameEntry" Text="{Binding Path=Item.Name, Mode=TwoWay}" />
<Entry x:Name="ValueEntry" Text="{Binding Path=Item.Value, Mode=TwoWay}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0" Text="Cancel" Clicked="OnCancelButtonClicked" />
<Button Grid.Column="1" Grid.Row="0" Text="Add" Command="{Binding NewCommand}" CommandParameter="{Binding Item}" Clicked="OnCommitButtonClicked" IsVisible="{Binding IsNewAction}" />
<Button Grid.Column="1" Grid.Row="0" Text="Save" Command="{Binding CommitCommand}" CommandParameter="{Binding Item}" Clicked="OnCommitButtonClicked" IsVisible="{Binding IsEditAction}" />
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
你能帮我弄清楚为什么列表视图在集合更改后不更新,比如添加或更新吗?删除操作工作得很好,它正确地更新了列表视图。
谢谢你的一切!
(我也尝试在主线程上调用操作,但没有奏效)
答: 暂无答案
评论
NewCommand
更新集合 - 这是从哪里来的?Coordinates