Mam problemy na Xamarin.Forms z ListView (i CollectionView też próbowałem). Miałem jakieś problemy z występami (wątek na forum XF), które są rozwiązane, ale mam jeszcze jeden problem: przedmioty nie są aktualizowane w "czasie rzeczywistym", gdy ich zmienia nieruchomość.
Mam obserwację z kategorii (która jest kolekcją wyniku) i kolejny pomostableczenie z wynikami, które mają właściwość Isfavorite ustawiona na true. Klasa wynikowa implementuje inotifyPropertyChanged (i oczywiście ustawienie ISFAVorite podnosi wydarzenie). Wyświetlam je w 2 listach, w 2 różnych zakładkach (za pomocą tababdepage): Każda komórka ma jakiś tekst i przycisk z tekstem wiązanym z wynikiem.ISFavorite.
Problem: Po naciśnięciu tego przycisku lista ulubionych jest prawidłowo modyfikowany, a komórka w głównym liścionie jest modyfikowana też ... ale muszę przewijać w dół i do góry, aby odpowiednia Viewcell zniknie, a następnie pojawi się ponownie, aby zobaczyć zmianę . W przeciwnym razie przycisk. Tekst zachowuje starej wartości!
Niektóre kod:
Wynik i klasy kategorii:
public class Score : HasPropertyChanging, IComparable<Score>
{
// Other properties...
// The HasPropertyChanging abstract class implements INotifyPropertyChanged
private bool _isFavorite;
public bool IsFavorite { get => _isFavorite; set => _isFavorite = SetFieldValueAndNotify(value); }
}
public class Category : ObservableCollection<Score>
{
public string Name { get; set; }
}
Viewmodel:
public class ScoreListViewModel : ViewModelBase
{
// Lists of categories and scores : Categories<Score> (not ordered) / all scores (order AZ) / favorites (order AZ)
public ObservableCollection<Category> Categories { get; set; } = new ObservableCollection<Category>();
public ObservableCollection<Score> Scores { get; set; } = new ObservableCollection<Score>();
public ObservableCollection<Score> FavoriteScores { get; set; } = new ObservableCollection<Score>();
public ScoreListViewModel()
{
this.InitializeScoreList();
}
// Toggle favorite status (raised from ICommand in XAML)
public void ToggleFavorites(Score score)
{
score.IsFavorite = !score.IsFavorite;
if (score.IsFavorite)
this.FavoriteScores.AddSorted(score);
else
this.FavoriteScores.Remove(score);
}
}
I widok:
<?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:CardioCALC"
x:Class="CardioCALC.ScoreListPage"
x:Name="ThisPage"
x:DataType="viewmodels:ScoreListViewModel"
BindingContext="{x:Static viewmodels:ScoreListViewModel.Instance}">
<ListView
ItemsSource="{Binding Categories}"
IsGroupingEnabled="True"
GroupDisplayBinding="{Binding Name}"
HasUnevenRows="True"
CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate x:DataType="viewmodels:Score">
<ViewCell Height="70">
<Grid BackgroundColor="White" Padding="20, 5, 10, 5">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1.5*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Label Text="{Binding DisplayName}" FontSize="17" Grid.Column="0" Grid.Row="0" />
<Label Text="{Binding Detail}" FontSize="13" Opacity="0.6" Grid.Column="0" Grid.Row="1" />
<Button Text="{Binding IsFavorite, Converter={StaticResource FavoritesDisplayValueConverter}}" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"
Clicked="OnFavButtonClicked"
Command="{Binding Source={x:Reference ThisPage}, Path=ToogleFavorites}" CommandParameter="{Binding .}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
(Uwaga: Uprościłem trochę widoku, który wykorzystuje instancję singleton, która ma być udostępniona między 2 stronami ...)
Ktoś ma pomysł?
Dzięki, Olivier.
2 odpowiedzi
Cóż, pewna aktualizacja ...
Zrobiłem bardzo duży błąd podczas implementacji inotifypropertyChanged w moim ViewModelbase ... Nie wiem, dlaczego nie zauważyłem tego wcześniej, ponieważ nie było funkcji na innych stronach ...
Używałem metody, która podnosi imprezę randkowej, a następnie zwraca wartość dla nieruchomości. Robię to, mogłem pisać:
protected T SetPropertyValueAndNotify(T value, [CallerMemberName] string propertyName = null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
return value;
}
private bool _myProperty;
public bool MyProperty
{
get => _myProperty;
set => _myProperty = SetPropertyValueAndNotify(value);
}
ALE ! Robię to, powiadomiłem szablon XAML tylko podczas zmiany nieruchomości dwa razy !!
Więc ... rozwiązany i przepraszam! Olivier.
Dobrze,
Na razie muszę użyć sztuczki: metoda OnfavbuttonClicked robi to:
Button button = sender as Button;
button.Text = ((Score)button.BindingContext).IsFavorite.ToString();
Działa to, ale wygląda bardzo źle i jest niekompletne, ponieważ mam w rzeczywistości 2 listaview w 2 zakładkach, które dzielą te same obiekty (wynik), więc chciałbym, aby zmiany w jednym listaview aktualizuje inne ...
Dowolny pomysł ?
Podobne pytania
Nowe pytania
listview
ListView to graficzny element sterujący lub widget udostępniany przez biblioteki interfejsu użytkownika w większości nowoczesnych systemów operacyjnych w celu wyświetlania elementów w formie listy.