我有一个longlistselector,每行都有ToggleSwitch,我想在更改ToggleSwitch时通过我的ApiService调用http请求。由于注入,我在ViewModel中有ApiService类,在ViewModel中我有带有开关的模块的ObservableCollection。我用datatemplate绑定它,绑定ToggleSwitch到bool属性没有问题。但是我应该在该属性的制定者中做些什么呢?
模型 - Modul.cs
public int IsLock
{
get { return isLock; }
set {
Set(() => IsLock, ref isLock, value);
// What should I do here? How call ViewModel method?
}
}
ViewModel - ModuleListViewModel.cs
public ObservableCollection<Module> Modules { get; private set; }
// here I have apiService instance
// and here I could call apiService.Lock(module) and so on
查看 - DataTemplate的一部分
<toolkit:ToggleSwitch x:Name="LockSwitch"
IsChecked="{Binding IsLock, Mode=TwoWay}"/>
对此有什么正确的方法?也许我可以在每个Modul类中使用ApiService类,但我认为这非常糟糕。我认为ViewModel应该以某种方式发现模型已被更改,它应该调用方法。
答案 0 :(得分:2)
我建议使用ToggleSwitch的Command
属性 - 每次用户更改切换时都会执行该属性,并允许您绑定到父数据上下文。在XAML中使用类似的东西:
<ItemsControl x:Name="items" ItemsSource="{Binding Modules}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:ToggleSwitch x:Name="LockSwitch"
Command="{Binding ElementName=items,Path=DataContext.LockToggleCommand}"
CommandParameter="{Binding}"
IsChecked="{Binding IsLock, Mode=TwoWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
然后只需添加&#34; LockToggleCommand&#34;到您的主视图模型,并调用服务,例如:
public ObservableCollection<Module> Modules { get; private set; }
public ICommand LockToggleCommand { get; private set; }
public ViewModel()
{
LockToggleCommand = new DelegateCommand<Module>(module => {
apiService.Lock(module);
});
}
这里&#34; DelegateCommand&#34;只是ICommand
的通常实现 - 我确信MVVM Light有自己的标准实现。
修改强>
我认为ToggleSwitch
支持Command
,但由于它没有,您可以采用类似的方法使用EventTrigger(如果您愿意添加System.Windows.Interactivity和Microsoft.Expression.Interactions DLL到您的项目):
<ItemsControl x:Name="items" ItemsSource="{Binding Modules}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:ToggleSwitch x:Name="LockSwitch"
IsChecked="{Binding IsLock, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Toggled">
<ei:CallMethodAction TargetObject="{Binding ElementName=items,Path=DataContext}"
MethodName="OnToggled"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
现在添加&#34; OnToggled&#34;主视图模型的方法 - 使用&#34; sender&#34;获取当前项目的参数,如下所示:
public void OnToggled(object sender, RoutedEventArgs e)
{
var toggleSwitch = (ToggleSwitch)sender;
var module = (Module)toggleSwitch.DataContext;
apiService.Lock(module);
}