홈>
Xamarin.Forms에서 크로스 플랫폼 앱을 개발 중입니다.
페이지 중 하나에 동일한 항목 목록을 가진 3 개의 피커 세트를 표시해야합니다. 아이디어는 피커 중 하나에서 항목을 선택하면 다른 두 항목의 항목 소스에서 제거된다는 것입니다.
이를 위해 다음 코드를 개발했습니다.
BaseList
라는 아이템 목록으로 시작했습니다
우리는 웹 서비스에서 얻을 수 있습니다. 또한 3 개의 개별 목록 (
ListA
)을 만듭니다.
ListB
그리고
ListC
) 및 각 피커의 선택된 항목 (
SelectedA
)을 저장할 항목 3 개
SelectedB
그리고
SelectedC
).
private List<Item> BaseList;
private List<Item> _ListA;
private Item _SelectedA;
private List<Item> _ListB;
private Item _SelectedB;
private List<Item> _ListC;
private Item _SelectedC;
…
//Api Calls
private void LoadData()
{
…
BaseList = new List<Item> (ListFromWebServices);
_ListA = new List<Item>(BaseList);
OnPropertyChanged(nameof(ListA));
_ListB = new List<Item>(BaseList);
OnPropertyChanged(nameof(ListB));
_ListC = new List<Item>(BaseList);
OnPropertyChanged(nameof(ListC));
}
…
//Public Fields
public List<Item> ListA
{
get
{
return _ListA;
}
}
public Item SelectedA
{
get
{
return _SelectedA;
}
set
{
SetProperty(ref _SelectedA, value, nameof(SelectedA));
}
}
public List<Item> ListB
{
get
{
return _ListB;
}
}
public Item SelectedB
{
get
{
return _SelectedB;
}
set
{
SetProperty(ref _SelectedB, value, nameof(SelectedB));
}
}
public List<Item> ListC
{
get
{
return _ListC;
}
}
public Item SelectedC
{
get
{
return _SelectedC;
}
set
{
SetProperty(ref _SelectedC, value, nameof(SelectedC));
}
}
이 코드는 ViewModel에 있으므로 SetProperty를 사용하여 참조 된 속성을 값으로 설정하고
PropertyChangedEventArgs
를 호출합니다.
INotifyPropertyChanged
에서
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
ItemSource를 업데이트하기 위해 선택된 항목이 변경 될 때마다
OnSelectedItemChanged
를 호출합니다
SelectedA
의 세터에서
SelectedB
그리고
SelectedC
. 이 메소드는 어떤 Picker가 트리거했는지를 나타내는 색인을받습니다 :
private void OnSelectedItemChanged(int index)
{
Item CurrentA = SelectedA;
Item CurrentB = SelectedB;
Item CurrentC = SelectedC;
int i;
switch (index)
{
case 0:
_ListB = new List<Item> (BaseList);
_ListB.Remove(CurrentA);
_ListB.Remove(CurrentC);
OnPropertyChanged(nameof(ListB));
_ListC = new List<Item>(BaseList);
_ListC.Remove(CurrentA);
_ListC.Remove(CurrentB);
OnPropertyChanged(nameof(ListC));
i = ListB.IndexOf(CurrentB);
if (i > -1)
{
_SelectedB = ListB[i];
}
OnPropertyChanged(nameof(SelectedB));
i = ListC.IndexOf(CurrentC);
if (i > -1)
{
_SelectedC = ListC[i];
}
OnPropertyChanged(nameof(SelectedC));
break;
case 1:
_ListA = new List<Item>(BaseList);
_ListA.Remove(CurrentB);
_ListA.Remove(CurrentC);
OnPropertyChanged(nameof(ListA));
_ListC = new List<Item>(BaseList);
_ListC.Remove(CurrentA);
_ListC.Remove(CurrentB);
OnPropertyChanged(nameof(ListC));
i = ListA.IndexOf(CurrentA);
if (i > -1)
{
_SelectedA = ListA[i];
}
OnPropertyChanged(nameof(SelectedA));
i = ListC.IndexOf(CurrentC);
if (i > -1)
{
_SelectedC = ListC[i];
}
OnPropertyChanged(nameof(SelectedC));
break;
case 2:
_ListA = new List<Item>(BaseList);
_ListA.Remove(CurrentB);
_ListA.Remove(CurrentC);
OnPropertyChanged(nameof(ListA));
_ListB = new List<Item>(BaseList);
_ListB.Remove(CurrentA);
_ListB.Remove(CurrentC);
OnPropertyChanged(nameof(ListB));
i = ListA.IndexOf(CurrentA);
if (i > -1)
{
_SelectedA = ListA[i];
}
OnPropertyChanged(nameof(SelectedA));
i = ListB.IndexOf(CurrentB);
if (i > -1)
{
_SelectedB = ListB[i];
}
OnPropertyChanged(nameof(SelectedB));
break;
}
}
우리가하는 일은 기본적으로 각 선택기에 대해 현재 선택된 항목을 별도의 변수에 저장하고
BaseList
를 복사하는 것입니다
이벤트를 호출하지 않은 두 개의 선택기로 들어간 다음 각 새 목록에서 다른 선택기로 사용중인 모든 옵션을 제거하고 각 새 목록에서 선택한 항목을 원래 선택한 항목으로 다시 설정하고 마지막으로
OnPropertyChanged()
를 호출하십시오.
변경 사항에 대한 정보를 제공합니다.
ItemSource
를 바꿀 때
선택기에서
SelectedItem
를 설정합니다.
null
로
. 전화
OnPropertyChanged()
OnSelectedItemChanged()
후 세터에
이 호출되면 한 피커가 다른 피커를 무한 루프로 연결하고 설정하기 전에 값이 null이 아닌지 확인하는 필터를 추가하면 피커에 선택된 항목이 표시되지 않고 값이 이미 설정되어 있습니다.- 답변 # 1
관련 질문
- 글꼴 변경 xamarin.android c#
- c# : 뷰 모델에서 속성을 찾을 수 없습니다.
- c# : Swift 프레임워크로 Xamarin.iOS 바인딩 프로젝트를 빌드할 수 없습니다.
- c# : Xamarin의 View 안에 모든 자식을 중첩하려면 어떻게 해야 하나요?
- 모델 클래스를 사용하지 않고 LINQ를 사용하여 c#에서 json 문자열을 구별하는 방법은 무엇입니까?
- c# : Xamarin 양식 ->공백을 표시하는 PopUpView, 제거하는 방법은 무엇입니까?
- c# : 참조 'System.Void System.Security.Cryptography.DSACng를 확인할 수 없습니다.
- c# : 내 UWP 응용 프로그램에서 .exe를 시작할 수 없습니다.
- c# : xamarin 형식에서 한 행의 라디오 버튼을 클릭하면 ListView 항목의 인덱스 가져오기
- c# : ModelViewControl에 XML 바인딩
누가 같은 문제를 겪을 경우를 대비하여 해결책을 찾았습니다. 당신이
CurrentA
를 만들면 밝혀CurrentB
그리고CurrentC
전역 변수 및 각 경우에if ((CurrentA != SelectedA) && (!(SelectedA is null))) { ... (do all the stuff) } break;
추가 그리고 마지막에작동합니다. 우리는 왜 tho :)