I'm trying to dynamically update an element's visibility by binding IsVisible to a getter property. However, the IsVisible does not automatically change the UI unless I refresh the page.
The following is the code snippet:
xaml:
<StackLayout>
<Picker Title="Choose..." ItemsSource="{Binding MyItemOptions}" SelectedItem="{Binding MyItem}"/>
<Label Text="MyItem is Milk" IsVisible="{Binding Path=IsMilkItem}"/>
</StackLayout>
C#:
private string _myItem;
public string MyItem
{
get => _myItem;
set
{
SetValue(ref _myItem, value);
}
}
public bool IsMilkItem
{
get { return MyItem == "Milk"; }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
bool response = false;
if (field == null ||
!field.Equals(value))
{
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
response = true;
}
return response;
}
The boolean property is updated in code after updating MyItem. However, the UI element does not automatically show up until i manually re-render the page.
I will be grateful if someone has a solution to this.
when you change the value of MyItem
, it does not raise a PropertyChanged
event for IsMilkItem
, so the UI is never told to update
public string MyItem
{
get => _myItem;
set
{
SetValue(ref _myItem, value);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsMilkItem"));
}
}
According to your description, you want to choose item from picker, when selecting item is Milk, you want to Label control is visible, Am I right?
If yes, I modify your code, you can take a look:
public partial class Page17 : ContentPage, INotifyPropertyChanged
{
public ObservableCollection<string> MyItemOptions { get; set; }
private string _MyItem;
public string MyItem
{
get { return _MyItem; }
set
{
_MyItem = value;
if(_MyItem== "Milk")
{
IsMilkItem = true;
}
else
{
IsMilkItem = false;
}
}
}
private bool _IsMilkItem;
public bool IsMilkItem
{
get { return _IsMilkItem; }
set
{
_IsMilkItem = value;
RaisePropertyChanged("IsMilkItem");
}
}
public Page17 ()
{
InitializeComponent ();
MyItemOptions = new ObservableCollection<string>()
{
"item 1",
"item 2",
"item 3",
"Milk"
};
this.BindingContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Update:
You can use Label trigger to set label isvisible, and don't need to IsMilkItem property to set Lable Isvisible.
<Picker x:Name="picker1" Title="Choose..." ItemsSource="{Binding MyItemOptions}" SelectedItem="{Binding MyItem}" />
<Label Text="MyItem is Milk" IsVisible="False" >
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference picker1},Path=SelectedItem}" Value="Milk">
<Setter Property="IsVisible"
Value="True"/>
</DataTrigger>
</Label.Triggers>
</Label>
Here is the .cs:
public ObservableCollection<string> MyItemOptions { get; set; }
private string _MyItem;
public string MyItem
{
get { return _MyItem; }
set
{
_MyItem = value;
}
}
public Page17 ()
{
InitializeComponent ();
MyItemOptions = new ObservableCollection<string>()
{
"item 1",
"item 2",
"item 3",
"Milk"
};
this.BindingContext = this;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.