[英]WP8 call method in viewmodel from object in collection
I have a longlistselector and in each row I have ToggleSwitch and I would like to call http request via my ApiService when ToggleSwitch is changed. 我有一个longlistselector,每行中都有ToggleSwitch,当ToggleSwitch更改时,我想通过ApiService调用http请求。 I have ApiService class in ViewModel thanks to injection and in ViewModel I have ObservableCollection of Modules which have switches. 由于注入,我在ViewModel中拥有ApiService类,在ViewModel中,我具有带有开关的Modules的ObservableCollection。 I bind it with datatemplate and there is no problem with bind ToggleSwitch to bool property. 我将其与datatemplate绑定,并且将ToggleSwitch绑定到bool属性没有问题。 But what should I do in setter of that property? 但是我应该如何处理该财产?
Model - Modul.cs 型号-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 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
View - part of DataTemplate 视图-DataTemplate的一部分
<toolkit:ToggleSwitch x:Name="LockSwitch"
IsChecked="{Binding IsLock, Mode=TwoWay}"/>
What's the right aproach for this? 正确的方法是什么? Maybe I could have ApiService class in each Modul class but I think that's very bad. 也许我可以在每个Modul类中都有ApiService类,但是我认为这很糟糕。 I think ViewModel should somehow findout that Model was changed and it should call method. 我认为ViewModel应该以某种方式发现Model已更改,并且应该调用method。
I suggest using the ToggleSwitch's Command
property -- that will get executed every time the user changes the toggle, and will allow you to bind to the parent data context. 我建议使用ToggleSwitch的Command
属性,该属性将在用户每次更改切换开关时执行,并允许您绑定到父数据上下文。 Use something like this in the XAML: 在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>
Then just add the "LockToggleCommand" to your main view model, and call the service, eg: 然后只需将“ LockToggleCommand”添加到您的主视图模型,然后调用服务,例如:
public ObservableCollection<Module> Modules { get; private set; }
public ICommand LockToggleCommand { get; private set; }
public ViewModel()
{
LockToggleCommand = new DelegateCommand<Module>(module => {
apiService.Lock(module);
});
}
Here "DelegateCommand" is just the usual implementation of ICommand
-- I am sure that MVVM Light has its own standard implementation. 在这里,“ DelegateCommand”只是ICommand
的常规实现-我确信MVVM Light具有自己的标准实现。
Edit 编辑
I thought that ToggleSwitch
supported Command
, but since it doesn't, you can take a similar approach using an EventTrigger (if you are willing to add the System.Windows.Interactivity and Microsoft.Expression.Interactions DLLs to your project): 我以为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>
Now add the "OnToggled" method to the main view model -- use the "sender" parameter to get the current item, something like this: 现在,将“ OnToggled”方法添加到主视图模型中-使用“ sender”参数获取当前项,如下所示:
public void OnToggled(object sender, RoutedEventArgs e)
{
var toggleSwitch = (ToggleSwitch)sender;
var module = (Module)toggleSwitch.DataContext;
apiService.Lock(module);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.