2017-06-19 52 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