我正在尝试实现一项功能,如果我打开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绑定并尝试更改事件上的数据&#39; OnPropertyChanged(&#34; IsActive&#34;)&#39;但无法实施。
任何建议都会有所帮助。
修改
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.
}
}
}
答案 0 :(得分:1)
要从AllProfiles
中的属性设置器访问ProfileItem
,您需要将ProfileItem
的引用添加到ViewModel,这在关注点分离方面不是一个好主意。我的建议是让ViewModel处理活动配置文件的更改。
为此,您需要将ViewModel订阅到每个项目的PropertyChanged
,并相应地处理IsActive
的更改。这有点痛苦,因为您需要最初订阅每个项目,取消订阅是否删除了ProfileItem
并订阅了在初始化VM后添加的新项目。
然而,根据我的经验,这种样板文件对于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;
}
}