사용자가 Xamarin의 단일 레이블에 두 개 이상의 필드 중 하나를 표시하도록 선택하는 방법

Nov 19 2020

단일 레이블을 사용하여 Xamarin Forms에서 두 데이터 필드 중 하나를 번갈아 표시하려고합니다. 레이블 1 만 바인딩 필드 (Contact_Name)를 표시하지만 "DisplayField"변수를 사용하려는 두 번째 레이블에는 'Contact_Address'또는 'Contact_eMail'이 표시되지 않습니다. 이전에 게시 된 질문과 다른 사용자가 도와 주려고했지만 작동하지 않았습니다!

모델 클래스

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; }
}

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>

코드 비하인드

 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;
   }
}

모델 클래스보기

 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));
  }
 }

답변

JuniorJiang-MSFT Nov 20 2020 at 02:30

IsVisible이를 달성하기 위해 속성을 사용할 수 있으며 하나의 레이블 만 바인딩 할 필요가 없습니다.

따라서 다음과 같이 StackLayout에서 두 개의 lables를 바인딩 Contact_Address하고 Contact_eMail사용합니다.

<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>

그런 다음 연락처 에서 두 개의 가시적 속성을 추가합니다.

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));
    }

}

이제 Contentpage에서 버튼을 클릭 할 때 표시 가능한 속성을 수정할 수 있습니다.

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;
    }
}

효과는 다음과 같습니다.