Comment un utilisateur choisit d'afficher 1 champ sur deux (ou plus) sur une seule étiquette dans Xamarin
J'essaie d'utiliser une seule étiquette pour afficher l'un des deux champs de données en alternance dans Xamarin Forms. Only Label 1 Affichage du champ de liaison (Contact_Name), tandis que le second Label que j'essaie d'utiliser une variable "DisplayField" n'affiche ni 'Contact_Address' ni 'Contact_eMail'. Question postée avant et un autre utilisateur a essayé d'aider mais cela n'a pas fonctionné!
Classe de modèle
public class Contacts
{
[PrimaryKey][Autoincrement]
public int Contact_ID { get; set; }
public string Contact_Name { get; set; }
public string Contact_Address { get; set; }
public string Contact_eMail { get; set; }
}
Page XAML
<StackLayout>
<Button Text="Display Address" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Fill" Clicked="Display_Address" />
<Button Text="Display Email" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Fill" Clicked="Display_eMail" />
<Entry HorizontalOptions="FillAndExpand" Text="{Binding DisplayField}" />
<ListView x:Name="listView" HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Orientation="Vertical" VerticalOptions="CenterAndExpand" >
<Frame >
<StackLayout Orientation="Vertical" VerticalOptions="Center">
<Label Text="{Binding Contact_Name}" FontSize="Medium" LineBreakMode="WordWrap" />
<Label Text="{Binding DisplayField}" LineBreakMode="WordWrap" />
</StackLayout>
</Frame>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Code derrière
public partial class FieldSwap : ContentPage
{
readonly FieldViewModel _fieldViewModel;
readonly SQLiteAsyncConnection _connection = DependencyService.Get<ISQLite>().GetConnection();
public ObservableCollection<Contacts> CList { get; set; }
public static string DisplayField { get; private set; }
public static int caseSwitch { get; private set; }
public FieldSwap()
{
InitializeComponent();
_fieldViewModel = new FieldViewModel();
_fieldViewModel.Field = "Contact_Address";
this.BindingContext = _fieldViewModel;
}
public static void SelectField()
{
switch (caseSwitch)
{
case 1:
DisplayField = "Contact_Address";
break;
case 2:
DisplayField = "Contact_eMail";
break;
default:
DisplayField = ("Contact_Address");
break;
}
}
private void Display_Address(object sender, EventArgs e)
{
caseSwitch = 1;
SelectField();
ReadData();
}
private void Display_eMail(object sender, EventArgs e)
{
caseSwitch = 2;
SelectField();
ReadData();
}
public void ReadData()
{
var list = _connection.Table<Contacts>().ToListAsync().Result;
CList = new ObservableCollection<Contacts>(list);
listView.ItemsSource = CList;
}
}
Voir la classe de modèle
public class FieldViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
String _field;
public string Field
{
set
{
if (!value.Equals(_field, StringComparison.Ordinal))
{
_field = value;
OnPropertyChanged("DisplayField");
}
}
get
{
return _field;
}
}
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
}
Réponses
Vous pouvez utiliser la IsVisible
propriété pour y parvenir, pas besoin de lier une seule étiquette.
Par conséquent, la liaison Contact_Address
et Contact_eMail
avec deux étiquettes dans StackLayout comme suit:
<StackLayout Orientation="Vertical" VerticalOptions="Center">
<Label Text="{Binding Contact_Name}" FontSize="Medium" LineBreakMode="WordWrap" />
<Label Text="{Binding Contact_Address}" IsVisible="{Binding AddressVisible}" LineBreakMode="WordWrap" />
<Label Text="{Binding Contact_eMail}" IsVisible="{Binding EMailVisible}" LineBreakMode="WordWrap" />
</StackLayout>
Ensuite, dans Contacts, ajoutez deux propriétés visibles:
public class Contacts: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
...
private bool addressVisible;
public bool AddressVisible
{
set
{
if (addressVisible != value)
{
addressVisible = value;
OnPropertyChanged("AddressVisible");
}
}
get
{
return addressVisible;
}
}
private bool eMailVisible;
public bool EMailVisible
{
set
{
if (eMailVisible != value)
{
eMailVisible = value;
OnPropertyChanged("EMailVisible");
}
}
get
{
return eMailVisible;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Maintenant, dans Contentpage, vous pouvez modifier la propriété visible lorsque le bouton est cliqué:
private void Display_Address(object sender, EventArgs e)
{
foreach(var item in CList )
{
item.AddressVisible = true;
item.EMailVisible = false;
}
}
private void Display_eMail(object sender, EventArgs e)
{
foreach (var item in CList )
{
item.AddressVisible = false;
item.EMailVisible = true;
}
}
Voici l'effet:
