在ListView中一次只打开一个开关
我正在尝试实现一种功能,如果我打开ListView中的任何开关,其他开关都应该关闭 以下是我的XAML:在ListView中一次只打开一个开关,listview,mvvm,binding,xamarin.forms,Listview,Mvvm,Binding,Xamarin.forms,我正在尝试实现一种功能,如果我打开ListView中的任何开关,其他开关都应该关闭 以下是我的XAML: <ListView ItemsSource="{Binding AllProfiles}" HasUnevenRows="True" SeparatorVisibility="None" RowHeight="-1"> <ListView.ItemTemplate> <DataTemplate> <Vi
<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.
}
}
}
公共类SetProfileViewModel:ViewModelBase
{
私有ObservableCollection _allProfiles=新ObservableCollection();
公共可观察收集所有配置文件
{
获取{return\u allProfiles;}
设置
{
_所有配置文件=值;
OnPropertyChanged(“所有配置文件”);
}
}
}
公共类配置文件:ViewModelBase
{
私有字符串\u名称;
私人字符串\u电子邮件;
私人楼宇是活跃的;
公共字符串名{
获取{return\u name;}
设置
{
_名称=值;
不动产变更(“名称”);
}
}
公共字符串电子邮件
{
获取{return\u email;}
设置
{
_电子邮件=价值;
OnPropertyChanged(“电子邮件”);
}
}
公共福利活动
{
获取{return\u isActive;}
设置
{
_i活跃=价值;
不动产变更(“不动产”);
//如何从这里更改“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;
}
}
公共类MyViewModel:INotifyPropertyChanged
{
私有bool_handleItemChanges=true;
公共可观察集合项{get;}
公共MyViewModel()
{
Items=新的ObservableCollection();
Items.CollectionChanged+=ItemsChanged;
}
公共无效项更改(对象s、集合ChangedEventArgs a)
{
如果(a.NewItems!=null)
foreach(a.NewItems.OfType中的变量i)
登记册(i);
//根据放行单(i)处理旧项目
//句柄集合重置
}
公共无效登记簿(ItemViewModel i)
{
i、 PropertyChanged+=ItemChanged;
}
公共作废发布(ItemViewModel i)
{
i、 PropertyChanged-=ItemChanged;
}
私有无效项已更改(对象s、PropertyChangedEventArgs a)
{
如果(!\u handleItemChanges)返回;
_handleItemChanges=false;
如果(a.PropertyName==“IsActive”)
//处理变化
_handleItemChanges=true;
}
}
如果您使用的是数据绑定,您只需在AllProfiles
集合中的项上迭代,并将属性设置为false。@GeraldVersluis。。谢谢你的回复。我做了一些改变。请参阅编辑。我正在尝试更改Profile类下“IsActive”中“AllProfiles”的项目数据。我该怎么做?谢谢@Marc。。你的解决方案奏效了。但是,我在这里面临着一个障碍。每次我在'ItemChanged'函数中更改属性值时,它都会根据更改的值的数量一次又一次地被调用。我尝试在更改之前释放,然后注册,但结果相同。请建议任何解决方法。@AkshatAgarwal我通常使用激活/停用处理的标志变量来避免此类循环。我已经更新了答案中的代码。希望这有帮助。