2017-06-19 74 views
0

我想實現一個功能,如果我打開ListView中的任何開關,其他開關應該關閉。在ListView裏面一次只打開一個開關

以下是我的XAML:

<ListView ItemsSource="{Binding AllProfiles}" HasUnevenRows="True" SeparatorVisibility="None" RowHeight="-1"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <ViewCell> 
       <StackLayout Orientation="Vertical" BackgroundColor="#F6F6F6"> 
        <Frame Padding="2" BackgroundColor="#FFFFFF" Margin="10,5,10,5"> 
         <StackLayout Orientation="Horizontal" BackgroundColor="#FFFFFF" Padding="20"> 
          <StackLayout Orientation="Vertical"> 
           <Label Text="{Binding Name}" TextColor="#FF6D9D" FontSize="25"></Label> 
           <Label Text="{Binding Email}" TextColor="#B1B1B1" FontSize="18"></Label> 
          </StackLayout> 
          <Switch HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand" IsToggled="{Binding IsActive}"> 
          </Switch> 
         </StackLayout> 
        </Frame> 
       </StackLayout> 
      </ViewCell> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

我使用MVVM綁定,並試圖改變事件的數據 'OnPropertyChanged( 「IsActive」)',但無法實施。

任何建議都會有幫助。

編輯:

public class SetProfileViewModel:ViewModelBase 
{   
    private ObservableCollection<Profile> _allProfiles = new ObservableCollection<Profile>(); 

    public ObservableCollection<Profile> AllProfiles 
    { 
     get { return _allProfiles; } 
     set 
     { 
      _allProfiles = value; 
      OnPropertyChanged("AllProfiles"); 
     } 
    } 
} 

public class Profile:ViewModelBase 
{ 
    private string _name; 
    private string _email; 
    private bool _isActive; 
    public string Name { 
     get { return _name; } 
     set 
     { 
      _name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 
    public string Email 
    { 
     get { return _email; } 
     set 
     { 
      _email = value; 
      OnPropertyChanged("Email"); 
     } 
    } 
    public bool IsActive 
    { 
     get { return _isActive; } 
     set 
     { 

      _isActive = value;     
      OnPropertyChanged("IsActive"); 
      //How can I change 'AllProfiles' data from here. 
     } 
    } 
} 
+1

如果您正在使用數據綁定,則應該遍歷「AllProfiles」集合中的項並將該屬性設置爲false。 –

+0

@GeraldVersluis ..謝謝你的迴應。我做了改變。請參閱編輯。我試圖在Profile類下的'IsActive'中更改'AllProfiles'的項目數據。我怎樣才能做到這一點? –

回答

1

從屬性setter訪問AllProfilesProfileItem你需要從ProfileItem添加到視圖模型這不是在關注點分離而言是個好主意的參考。我的建議是讓ViewModel處理活動配置文件的更改。

爲此,您需要訂閱每個項目的ViewModel到PropertyChanged並相應地處理IsActive的更改。這有點痛苦,因爲您最初需要訂閱每個項目,如果刪除了ProfileItem,則取消訂閱並訂閱在虛擬機初始化後添加的新項目。

但是,從我的經驗來看,這種樣板文件對MVVM來說很常見。一般模式是:

public class MyViewModel : INotifyPropertyChanged 
{ 
    private bool _handleItemChanges = true; 

    public ObservableCollection<ItemViewModel> Items { get; } 

    public MyViewModel() 
    { 
     Items = new ObservableCollection<ItemViewModel>(); 
     Items.CollectionChanged += ItemsChanged;   
    } 

    public void ItemsChanged(object s, CollectionChangedEventArgs a) 
    { 
     if (a.NewItems != null) 
      foreach(var i in a.NewItems.OfType<ItemViewModel>) 
       Register(i); 

     // Handle old items accordingly with Release(i) 
     // Handle collection reset 
    } 

    public void Register(ItemViewModel i) 
    { 
     i.PropertyChanged += ItemChanged; 
    } 

    public void Release(ItemViewModel i) 
    { 
     i.PropertyChanged -= ItemChanged; 
    } 

    private void ItemChanged(object s, PropertyChangedEventArgs a) 
    { 
     if (!_handleItemChanges) return; 
     _handleItemChanges = false; 

     if (a.PropertyName == "IsActive") 
      // Handle the change 

     _handleItemChanges = true; 
    } 
} 
+0

Thanks @Marc ..你的解決方案工作。但是,我在這裏面臨着障礙。每次我改變'ItemChanged'函數中的屬性值時,它會一次又一次地被調用,取決於改變的值的數量。我在嘗試發佈前嘗試發佈然後註冊,但結果相同。請提出任何解決方法。 –

+0

@AkshatAgarwal我通常避免使用激活/禁用處理的標誌變量的這些循環。我在我的答案中更新了代碼。希望這可以幫助。 – Marc