英文:
How do i solve this strange error in my .Net MAUI page?
问题
尝试学习MAUI时,我准备了一个页面,其中有一个被隐藏的标签。在某个事件发生时,该标签变为可见。一切都正常工作,但当我将这个标签放入“CollectionView”并尝试将其与数据库中的值绑定时,该标签会出现“在当前上下文中不存在”的错误,如图所示。我犯了什么错误?谢谢!
英文:
Trying to learn MAUI i prepare a page where there is a Label that is hidden. At a certain event the label becomes visible. All it works ok, but when i put this label inside a "CollectionView" trying to bind her with a value from a database the Label become "not existing in the current context" with the error shown in this picture. Where is the error that i made? Thanks!
答案1
得分: 0
是的,您不能在模板中使用 x:Name
引用项目。您可以使用数据绑定从您的 ViewModel 控制模板化的 UI 元素,就像 Jason 所说的那样。
根据您的代码,我创建了一个演示并实现了这个功能。
您可以参考以下代码:
- 尝试为您的 Item 模型添加一个新属性
IsVisible
,并将其绑定到您的 LabelMatricola
。同时,您还需要为您的 Item 实现INotifyPropertyChanged
接口,如果更改项目的属性IsVisible
的值,UI 将自动刷新。
public class Item : INotifyPropertyChanged
{
public int Id { get; set; }
public int Value { get; set; }
public string Matricola { get; set; }
// 添加属性 IsVisible
private bool _isVisible;
public bool IsVisible
{
set { SetProperty(ref _isVisible, value); }
get { return _isVisible; }
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
- 创建 ViewModel (
TestViewModel.cs
)
public class TestViewModel : BaseViewModel
{
// 在此 ViewModel 中添加其他代码
public ObservableCollection<Item> Items { get; private set; }
public TestViewModel()
{
Items = new ObservableCollection<Item>();
Items.Add(new Item { Id = 01, Value = 10, Matricola = "test1" });
Items.Add(new Item { Id = 02, Value = 13, Matricola = "test2" });
Items Add(new Item { Id = 03, Value = 16, Matricola = "test3" });
}
}
- 使用示例:
TestPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiContentViewApp.TestPage"
xmlns:MauiContentViewApp="clr-namespace:MauiContentViewApp;assembly=MauiContentViewApp"
Title="TestPage">
<VerticalStackLayout>
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Entry Grid.Column="0"
BackgroundColor="Yellow"
Text="{Binding Value}"
Completed="Entry_Completed"
VerticalOptions="Center"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Matricola}"
IsVisible="{Binding IsVisible}"
FontAttributes="Italic"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
TestPage.xaml.cs
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
BindingContext = new TestViewModel();
}
private void Entry_Completed(object sender, EventArgs e)
{
// 在这里,我们可以获取编辑后的对象并更改此项目的属性 `IsVisible` 的值,然后 `Matri` Label 的 `IsVisible` 将被更新。
Item item = (Item)((Entry)sender).BindingContext;
if (item != null && !item.IsVisible)
{
item.IsVisible = true;
}
}
}
我已经提供了翻译好的部分,如果您需要更多帮助,请告诉我。
英文:
Yes,you cannot reference item inside a template by x:Name
. You can use data binding to control templated UI elements from your ViewModel, just as Jason said.
Based on your code, I created a demo and achieved this function.
You can refer to the following code:
1.try to add a new property IsVisible
to your Item model, and bind it to your Label Matr
. And you also need to implement interface INotifyPropertyChanged
for your Item, if you change the value of item's property IsVisible
, the UI will refresh automatically.
public class Item: INotifyPropertyChanged
{
public int Id { get; set; }
public int Value { get; set; }
public string Matricola { get; set; }
// add property IsVisible
private bool _isVisible;
public bool IsVisible
{
set { SetProperty(ref _isVisible, value); }
get { return _isVisible; }
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
2.create viewmodel (TestViewModel.cs
)
public class TestViewModel:BaseViewModel
{
//add other code in this ViewModel
public ObservableCollection<Item> Items { get; private set; }
public TestViewModel() {
Items = new ObservableCollection<Item>();
Items.Add(new Item { Id = 01, Value = 10, Matricola = "test1"});
Items.Add(new Item { Id = 02, Value = 13, Matricola = "test2" });
Items.Add(new Item { Id = 03, Value = 16, Matricola = "test3" });
}
3.Usage example:
TestPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiContentViewApp.TestPage"
xmlns:MauiContentViewApp="clr-namespace:MauiContentViewApp;assembly=MauiContentViewApp"
Title="TestPage">
<VerticalStackLayout>
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Entry Grid.Column="0"
BackgroundColor="Yellow"
Text="{Binding Value}"
Completed="Entry_Completed"
VerticalOptions="Center"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Matricola}"
IsVisible="{Binding IsVisible}"
FontAttributes="Italic"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
TestPage.xaml.cs
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
BindingContext = new TestViewModel();
}
private void Entry_Completed(object sender, EventArgs e)
{// here we can get the edited object and change the value of property `IsVisible` of this item ,then the `IsVisible` of `Matri` Label will be updated.
Item item = (Item)((Entry)sender).BindingContext;
if (item!=null && !item.IsVisible) {
item.IsVisible= true;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论