包含在 TabbedPage 中的 ListView 未从 Binding 更新
ListView contained in a TabbedPage not updating from Binding
在下面的代码中,我将 Records 绑定到一个使用 observablecollection 的视图模型中,我还提高了 inotifypropertychange,现在我有一个使用 navigation.pushasync 方法转到新页面的按钮设置,在那里我正在更新数据库记录,我在这个新页面中创建了一个列表视图并使用此处显示的相同绑定来绑定记录,每当我添加它更新的内容时,但是如果我按下后退按钮并返回到这个 EntryTabPage绑定不更新,只有在我完全关闭应用程序并重新启动它时才会更新显示数据。
我想更新此列表视图,但不确定该怎么做,我尝试使用 onappearing 并在 Listviewname.itemssource=Records 中输入;但这显示了一个错误 "this does not exist in the current context" 任何在正确方向上的帮助将不胜感激。
注意:绑定在除标签页之外的其他地方有效。
这是层次结构 TabbedPage->ContentPage->StackLayout->ListView(在此列表视图中,绑定不会更新。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bunk_Master.EntryPageTab1"
Title="Default">
<StackLayout x:Name="stacklayout">
<ListView ItemsSource="{Binding Records}"
x:Name="classListView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding}">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="new"
x:Name="addclassbutton">
</Button>
</StackLayout>
namespace Bunk_Master
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EntryPageTab1 : ContentPage
{
public EntryPageTab1()
{
InitializeComponent();
BindingContext = new ClassViewModel();
addclassbutton.Clicked += async (object sender, EventArgs e) =>
{
await this.Navigation.PushAsync(new AddClass());
};
}
protected override void OnAppearing()
{
base.OnAppearing();
}
}
}
这是 ViewModel
namespace Bunk_Master
{
public class ClassViewModel : BaseViewModel
{
readonly Database db;
public string classname { get; set; }
// public int absentnos { get; set; }
// public int presentnos { get; set; }
public ICommand AddCommand { get; set; }
public ICommand DeleteCommand { get; set; }
public ObservableCollection<string> Records { get; set; }
public ClassViewModel()
{
AddCommand = new Command(Add);
DeleteCommand = new Command(Delete);
db = new Database("classdb");
db.CreateTable<ClassModel>();
Records = new ObservableCollection<string>();
ShowAllRecords();
}
void Add()
{
var record = new ClassModel
{
classname = classname,
//absentnum = absentnos,
//presentnum = presentnos
};
db.SaveItem(record);
Records.Add(record.ToString());
RaisePropertyChanged(nameof(Records));
ClearForm();
}
private void Delete(object obj)
{
throw new NotImplementedException();
}
void ClearForm()
{
classname = string.Empty;
RaisePropertyChanged(nameof(classname));
}
void ShowAllRecords()
{
Records.Clear();
var classdb = db.GetItems<ClassModel>();
foreach (var classmodel in classdb)
{
Records.Add(classmodel.ToString());
}
}
}
}
这是我实现 Inotifypropertychange 的地方
namespace Bunk_Master
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
var handler = PropertyChanged;
if (handler == null) return;
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
如果有人碰巧发现 class 在一个 class 中工作但在另一个 class 中不工作并且您的代码是完美的,那只是因为 class 您实例化了必须使用而不是实例化一个新的。
只需添加这一行即可修复我的代码
public static Workingclass classInstance = new Workingclass;
然后我在其他 classes 中使用 classIncstance 而不是创建新实例,并且数据正在正确更新。
注意:我想删除这个 post 但是互联网上还有很多其他类似的 post 没有人解决这个简单的问题也许有人可以找到它有用。
在您的 Class ViewModel 中进行如下更改并尝试。
namespace Bunk_Master
{
public class ClassViewModel : BaseViewModel
{
readonly Database db;
public string classname { get; set; }
// public int absentnos { get; set; }
// public int presentnos { get; set; }
public ICommand AddCommand { get; set; }
public ICommand DeleteCommand { get; set; }
public ObservableCollection<string> _records;
public ObservableCollection<string> Records
{
get { return _records; }
set
{
_records = value;
RaisePropertyChanged();
}
}
public ClassViewModel()
{
AddCommand = new Command(Add);
DeleteCommand = new Command(Delete);
db = new Database("classdb");
db.CreateTable<ClassModel>();
_records = new ObservableCollection<string>();
ShowAllRecords();
}
void Add()
{
var record = new ClassModel
{
classname = classname,
//absentnum = absentnos,
//presentnum = presentnos
};
db.SaveItem(record);
_records.Add(record.classname.ToString());
ClearForm();
}
private void Delete(object obj)
{
throw new NotImplementedException();
}
void ClearForm()
{
classname = string.Empty;
}
void ShowAllRecords()
{
_records.Clear();
var classdb = db.GetItems<ClassModel>();
foreach (var classmodel in classdb)
{
_records.Add(classmodel.ToString());
}
}
}
}
您可能需要使用 this.DataContext = this;
才能正常工作。在我的例子中,如果我在分配 ItemsSource 之前打印 MessageBox.Show() ,它只会显示列表。我通过添加上面的行来修复它。
希望对您有所帮助!
在下面的代码中,我将 Records 绑定到一个使用 observablecollection 的视图模型中,我还提高了 inotifypropertychange,现在我有一个使用 navigation.pushasync 方法转到新页面的按钮设置,在那里我正在更新数据库记录,我在这个新页面中创建了一个列表视图并使用此处显示的相同绑定来绑定记录,每当我添加它更新的内容时,但是如果我按下后退按钮并返回到这个 EntryTabPage绑定不更新,只有在我完全关闭应用程序并重新启动它时才会更新显示数据。
我想更新此列表视图,但不确定该怎么做,我尝试使用 onappearing 并在 Listviewname.itemssource=Records 中输入;但这显示了一个错误 "this does not exist in the current context" 任何在正确方向上的帮助将不胜感激。
注意:绑定在除标签页之外的其他地方有效。 这是层次结构 TabbedPage->ContentPage->StackLayout->ListView(在此列表视图中,绑定不会更新。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bunk_Master.EntryPageTab1"
Title="Default">
<StackLayout x:Name="stacklayout">
<ListView ItemsSource="{Binding Records}"
x:Name="classListView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding}">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="new"
x:Name="addclassbutton">
</Button>
</StackLayout>
namespace Bunk_Master
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EntryPageTab1 : ContentPage
{
public EntryPageTab1()
{
InitializeComponent();
BindingContext = new ClassViewModel();
addclassbutton.Clicked += async (object sender, EventArgs e) =>
{
await this.Navigation.PushAsync(new AddClass());
};
}
protected override void OnAppearing()
{
base.OnAppearing();
}
}
}
这是 ViewModel
namespace Bunk_Master
{
public class ClassViewModel : BaseViewModel
{
readonly Database db;
public string classname { get; set; }
// public int absentnos { get; set; }
// public int presentnos { get; set; }
public ICommand AddCommand { get; set; }
public ICommand DeleteCommand { get; set; }
public ObservableCollection<string> Records { get; set; }
public ClassViewModel()
{
AddCommand = new Command(Add);
DeleteCommand = new Command(Delete);
db = new Database("classdb");
db.CreateTable<ClassModel>();
Records = new ObservableCollection<string>();
ShowAllRecords();
}
void Add()
{
var record = new ClassModel
{
classname = classname,
//absentnum = absentnos,
//presentnum = presentnos
};
db.SaveItem(record);
Records.Add(record.ToString());
RaisePropertyChanged(nameof(Records));
ClearForm();
}
private void Delete(object obj)
{
throw new NotImplementedException();
}
void ClearForm()
{
classname = string.Empty;
RaisePropertyChanged(nameof(classname));
}
void ShowAllRecords()
{
Records.Clear();
var classdb = db.GetItems<ClassModel>();
foreach (var classmodel in classdb)
{
Records.Add(classmodel.ToString());
}
}
}
}
这是我实现 Inotifypropertychange 的地方
namespace Bunk_Master
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
var handler = PropertyChanged;
if (handler == null) return;
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
如果有人碰巧发现 class 在一个 class 中工作但在另一个 class 中不工作并且您的代码是完美的,那只是因为 class 您实例化了必须使用而不是实例化一个新的。
只需添加这一行即可修复我的代码
public static Workingclass classInstance = new Workingclass;
然后我在其他 classes 中使用 classIncstance 而不是创建新实例,并且数据正在正确更新。
注意:我想删除这个 post 但是互联网上还有很多其他类似的 post 没有人解决这个简单的问题也许有人可以找到它有用。
在您的 Class ViewModel 中进行如下更改并尝试。
namespace Bunk_Master
{
public class ClassViewModel : BaseViewModel
{
readonly Database db;
public string classname { get; set; }
// public int absentnos { get; set; }
// public int presentnos { get; set; }
public ICommand AddCommand { get; set; }
public ICommand DeleteCommand { get; set; }
public ObservableCollection<string> _records;
public ObservableCollection<string> Records
{
get { return _records; }
set
{
_records = value;
RaisePropertyChanged();
}
}
public ClassViewModel()
{
AddCommand = new Command(Add);
DeleteCommand = new Command(Delete);
db = new Database("classdb");
db.CreateTable<ClassModel>();
_records = new ObservableCollection<string>();
ShowAllRecords();
}
void Add()
{
var record = new ClassModel
{
classname = classname,
//absentnum = absentnos,
//presentnum = presentnos
};
db.SaveItem(record);
_records.Add(record.classname.ToString());
ClearForm();
}
private void Delete(object obj)
{
throw new NotImplementedException();
}
void ClearForm()
{
classname = string.Empty;
}
void ShowAllRecords()
{
_records.Clear();
var classdb = db.GetItems<ClassModel>();
foreach (var classmodel in classdb)
{
_records.Add(classmodel.ToString());
}
}
}
}
您可能需要使用 this.DataContext = this;
才能正常工作。在我的例子中,如果我在分配 ItemsSource 之前打印 MessageBox.Show() ,它只会显示列表。我通过添加上面的行来修复它。
希望对您有所帮助!