英文:
Having issue with Bindable value in XAML page
问题
我有一段代码,是一个示例保龄球总结,其中输入了3场比赛并在"Series"列中进行了汇总。我遇到的问题是"Series"列没有得到我期望的更新。显然,我做错了一些事情,但我看不出我到底做错了什么。以下是支持该应用程序的代码:
<?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="HoriView.MainPage">
<StackLayout>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Image
Source="dotnet_bot.png"
HeightRequest="200"
HorizontalOptions="Center" />
<Label
Text="Hello, Bowlers!"
FontSize="32"
HorizontalOptions="Center" />
<Label
Text="Bowling Recap Snippet"
FontSize="18"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ScrollView>
<ScrollView>
<HorizontalStackLayout HorizontalOptions="Center">
<CollectionView SelectionMode="Single" ItemsSource="{Binding scores}" ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Game}" FontSize="Medium" WidthRequest="83" VerticalOptions="Center" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End"></Label>
<Entry Grid.Row="1" Text="{Binding Score}" TextChanged="UpdateGame" Keyboard="Numeric" ReturnType="Next" Placeholder="Game" WidthRequest="83" FontSize="Medium" ></Entry>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</HorizontalStackLayout>
</ScrollView>
</StackLayout>
</ContentPage>
using System.Collections.ObjectModel;
namespace HoriView;
public partial class MainPage : ContentPage
{
public ObservableCollection<Games> scores { get; set; }
string header = "Game";
public MainPage()
{
InitializeComponent();
scores= new ObservableCollection<Games>();
for(int i=0; i<4; i++)
{
if (i == 3)
{
header = "Series";
}
else
{
header = "Game" + (i+1).ToString();
}
scores.Add(new Games()
{
Game=header,
Score=0
});
}
BindingContext = this;
}
public void UpdateGame(object sender, TextChangedEventArgs e)
{
scores[scores.Count-1].Score = 0;
for(int i=0; i< scores.Count-1; i++)
{
scores[scores.Count - 1].Score += scores[i].Score;
}
}
}
public class Games
{
public string Game { get; set; }
public int Score { get; set; }
}
希望能提供帮助。谢谢。
英文:
I have code that is a sample bowling recap where 3 games are entered and are summarized in a Series column. The problem that I am experiencing is the Series column is not getting updated as I anticipate. Obviously, I am doing something wrong but can not see what I am doing wrong. Below is the code that supports the application:
<?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="HoriView.MainPage">
<StackLayout>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Image
Source="dotnet_bot.png"
HeightRequest="200"
HorizontalOptions="Center" />
<Label
Text="Hello, Bowlers!"
FontSize="32"
HorizontalOptions="Center" />
<Label
Text="Bowling Recap Snippet"
FontSize="18"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ScrollView>
<ScrollView>
<HorizontalStackLayout HorizontalOptions="Center">
<CollectionView SelectionMode="Single" ItemsSource="{Binding scores}" ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Game}" FontSize="Medium" WidthRequest="83" VerticalOptions="Center" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End"></Label>
<Entry Grid.Row="1" Text="{Binding Score}" TextChanged="UpdateGame" Keyboard="Numeric" ReturnType="Next" Placeholder="Game" WidthRequest="83" FontSize="Medium" ></Entry>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</HorizontalStackLayout>
</ScrollView>
</StackLayout>
</ContentPage>
using System.Collections.ObjectModel;
namespace HoriView;
public partial class MainPage : ContentPage
{
public ObservableCollection<Games> scores { get; set; }
string header = "Game";
public MainPage()
{
InitializeComponent();
scores= new ObservableCollection<Games>();
for(int i=0; i<4; i++)
{
if (i == 3)
{
header = "Series";
}
else
{
header = "Game" + (i+1).ToString();
}
scores.Add(new Games()
{
Game=header,
Score=0
});
}
BindingContext = this;
}
public void UpdateGame(object sender, TextChangedEventArgs e)
{
scores[scores.Count-1].Score = 0;
for(int i=0; i< scores.Count-1; i++)
{
scores[scores.Count - 1].Score += scores[i].Score;
}
}
}
public class Games
{
public string Game { get; set; }
public int Score { get; set; }
}
Any help would be appreciated. Thanks.
答案1
得分: 0
你的 Games
类没有实现 INotifyPropertyChanged
接口。
你可以手动实现它:
public class Games : INotifyPropertyChanged
{
private string _game;
public string Game
{
get => _game;
set
{
if(_game == value) return;
_game = value;
OnPropertyChanged();
}
}
private int _score;
public int Score
{
get => _score;
set
{
if(_score == value) return;
_score = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
或者,你也可以继承自 MVVM Community Toolkit 中的 ObservableObject
,然后使用 Source Generators 简单地定义如下:
public partial class Games : ObservableObject
{
[ObservableProperty]
private string _game;
[ObservableProperty]
private int _score;
}
在这种情况下,你只需要定义后备字段,Source Generators 将为你创建大写的可观察属性 Game
和 Score
。
英文:
Your Games
class doesn't implement the INotifyPropertyChanged
interface.
You can either implement that manually:
public class Games : INotifyPropertyChanged
{
private string _game;
public string Game
{
get => _game;
set
{
if(_game == value) return;
_game = value;
OnPropertyChanged();
}
}
private int _score;
public int Score
{
get => _score;
set
{
if(_score == value) return;
_score = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Alternatively, you could also inherit from ObservableObject
from the MVVM Community Toolkit and then simply write the following using Source Generators:
public partial class Games : ObservableObject
{
[ObservableProperty]
private string _game;
[ObservableProperty]
private int _score;
}
In this case, you only define the backing fields and the Source Generators will create the uppercase, observable properties Game
and Score
for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论