WP8 从集合中的对象调用视图模型中的方法

本文关键字:视图 模型 方法 调用 对象 WP8 集合 | 更新日期: 2023-09-27 18:33:48

我有一个longlistselector,在每一行我都有ToggleSwitch,我想在切换开关被更改时通过我的ApiService调用http请求。由于注入,我在ViewModel中有ApiService类,在ViewModel中,我有带有开关的模块的可观察集合。我用数据模板绑定它,将切换开关绑定到布尔属性没有问题。但是我应该怎么做呢?

型号 - 模数.cs

public int IsLock
    {
        get { return isLock; }
        set { 
            Set(() => IsLock, ref isLock, value); 
            // What should I do here? How call ViewModel method?
        }
    }

视图模型 - 模块列表视图模型.cs

 public ObservableCollection<Module> Modules { get; private set; }
 // here I have apiService instance
 // and here I could call apiService.Lock(module) and so on

视图 - 数据模板的一部分

 <toolkit:ToggleSwitch x:Name="LockSwitch" 
                                      IsChecked="{Binding IsLock, Mode=TwoWay}"/>

对此有什么正确的方法?也许我可以在每个模块类中都有 ApiService 类,但我认为这非常糟糕。我认为ViewModel应该以某种方式发现模型已更改,并且应该调用方法。

WP8 从集合中的对象调用视图模型中的方法

我建议使用 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>

然后只需将"LockToggleCommand"添加到您的主视图模型中,并调用该服务,例如:

public ObservableCollection<Module> Modules { get; private set; }
public ICommand LockToggleCommand { get; private set; }
public ViewModel()
{
    LockToggleCommand = new DelegateCommand<Module>(module => {
        apiService.Lock(module);
    });
}

这里的"DelegateCommand"只是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>

现在将"OnToggled"方法添加到主视图模型中 - 使用"sender"参数获取当前项目,如下所示:

public void OnToggled(object sender, RoutedEventArgs e)
{
    var toggleSwitch = (ToggleSwitch)sender;
    var module = (Module)toggleSwitch.DataContext;
    apiService.Lock(module);
}