Open BenjaNapo opened 4 years ago
You have to set Mode = TwoWay
explicitly:
LaTeX="{Binding DomandaAttuale.Testo, Mode=TwoWay, Converter={StaticResource UrlDecoder}}"
Thanks, now it works on the main text but I'm still having the issue on the ListView (using Label it didn't happen)
Can you show code that related to binding to the ListView
? (Both XAML
and VM
parts)
<ListView
Margin="0,10,0,0"
ItemTapped="ListView_ItemTapped"
ItemsSource="{Binding DomandaAttuale.Risposte}"
SelectionMode="None"
VerticalOptions="Center">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="9*" />
</Grid.ColumnDefinitions>
<ia:Checkbox
Padding="0,3"
FillColor="{DynamicResource PrimaryColor}"
IsChecked="{Binding Selezionata}"
IsCheckedChanged="Checkbox_IsCheckedChanged"
OutlineColor="{DynamicResource PrimaryColor}"
Shape="Rectangle" />
<!--<Label
Grid.Column="1"
Padding="0,3"
Text="{Binding Testo, Converter={StaticResource UrlDecoder}}"
VerticalOptions="Center" />-->
<math:TextView
Grid.Column="1"
LaTeX="{Binding Testo, Converter={StaticResource UrlDecoder}, Mode=TwoWay}"
TextAlignment="Left"
VerticalOptions="Center" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The VM is a little bit messed up, that's the part where i change quest to show
private void AvviaDomanda(int index)
{
IndiceAttuale = index;
DomandaAttuale = Micro.Domande[IndiceAttuale - 1];
[...other code...]
}
Does DomandaAttuale
notify about its change?
public partial class Domanda : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("tipologia")]
public string Tipologia { get; set; }
[JsonProperty("testo")]
public string Testo { get; set; }
[JsonProperty("tempo_massimo")]
public int TempoMassimo { get; set; }
[JsonProperty("immagine")]
public string Immagine { get; set; }
public int TempoImpiegato { get; set; }
public int Index { get; set; }
[...other code...]
}
public partial class Risposta : INotifyPropertyChanged, ICloneable
{
public event PropertyChangedEventHandler PropertyChanged;
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("testo")]
public string Testo { get; set; }
[JsonProperty("corretta")]
public long? Corretta { get; set; }
[JsonProperty("associa")]
public string Associa { get; set; }
public bool Selezionata { get; set; }
[...other code...]
}
I'm using the NuGet package Fody.PropertyChanged to notify the changes, so theorically it should works
I specifically asked about class that contains DomandaAttuale
property.
Anyway, here is a simple sample:
I've used Fody.PropertyChanged as well.
Sorry the, did you mean these files?
public partial class IstanzaMicro : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("domande")]
public Domanda[] Domande { get; set; }
public Micro Micro;
[...various attributes...]
}
public partial class TestPage : ContentPage
{
public IstanzaMicro Micro { get; set; }
public Domanda DomandaAttuale { get; set; }
public int IndiceAttuale { get; set; }
[...various attributes...]
public TestPage(IstanzaMicro micro)
{
InitializeComponent();
Micro = micro;
BindingContext = this;
SetupVisualizers();
AvviaDomanda(1);
Micro.TempoImpiegato = 0;
TimerAlive = true;
BackButtonClickable = true;
Console.WriteLine(Micro);
StartCountdown();
}
private void AvviaDomanda(int index)
{
IndiceAttuale = index;
DomandaAttuale = Micro.Domande[IndiceAttuale - 1];
[...other code...]
}
private void ProssimaSchermata(object sender, EventArgs e)
{
if (IndiceAttuale < 5)
AvviaDomanda(++IndiceAttuale);
else
{
[...other code...]
}
}
As you can see DomandaAttuale change only on AvviaDomanda, and AvviaDomanda is called twice (on constructor, and in ProssimaSchermata)
Btw thanks for ListViewSample.zip, I noticed that you use RelayCommand, is it necessary to make it work?
As you can see DomandaAttuale change only on AvviaDomanda, and AvviaDomanda is called twice (on constructor, and in ProssimaSchermata)
But TestPage
itself doesn't implement INotifyPropertyChanged
interface therefore View
doesn't know that something is changed.
For now you can do
public partial class TestPage : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// the rest of your code
Though I'd suggest you to read some MVVM tutorial and move logic outside of TestPage.xaml.cs
.
Btw thanks for ListViewSample.zip, I noticed that you use RelayCommand, is it necessary to make it work?
No, it's unrelated. RelayCommand
is a way to react to Button.Click
. You can use any other implementation of ICommand
interface. I just take the one that I found simplest.
That's what happen when I add those lines... (even the first time doesn't work)
I tried to notify manually in this way:
public partial class TestPage : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Domanda domandaAttuale;
public Domanda DomandaAttuale
{
get { return domandaAttuale; }
set
{
domandaAttuale = value;
OnPropertyChanged();
}
}
protected void OnPropertyChanged([CallerMemberName] string domandaAttuale = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(domandaAttuale));
}
But it still not working
Though I'd suggest you to read some MVVM tutorial and move logic outside of
TestPage.xaml.cs
.
Yep, you are right, I started use Xamarin with MVC pattern, but I noticed that somethings not works with binding
And btw I don't understand why till I was using Label it was working, but when I replaced them with math:TextView it worked no more...
But it still not working
Odd. It should work. Are there are any warnings or binding errors in the Debug.Output? If you put breakpoint to the
domandaAttuale = value;
Does it go there?
In the end I resolved placing an empty Label as 3rd column:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="69">
<Grid VerticalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*" />
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ia:Checkbox
Grid.Column="0"
FillColor="{DynamicResource PrimaryColor}"
IsChecked="{Binding Selezionata}"
IsCheckedChanged="Checkbox_IsCheckedChanged"
OutlineColor="{DynamicResource PrimaryColor}"
Shape="Circle" />
<math:TextView
Grid.Column="1"
LaTeX="{Binding Testo, Converter={StaticResource UrlDecoder}, Mode=TwoWay}"
TextColor="{DynamicResource TextColor}"
VerticalOptions="Center" />
<Label Grid.Column="2" Text="" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
At start it shows well what's in DomandaAttuale.Testo but when DomandaAttuale change I need to modify LaTex in C# side because with binding it doesn't work. To resolved this I tried in this way:
DomandaAttuale.Testo = DomandaAttuale.Testo.Clone() as string;
but didn't workedI noticed the same issue when I load ItemSource of a ListView that contains math:TextView, the first time works but the others shows empty cells