WPF触发器按钮可以在ItemsControl中从ItemsControl外部执行

时间:2017-08-22 06:23:58

标签: c# wpf xaml mvvm

我正在尝试从WPF MVVM教程扩展应用程序作为练习。对于我在这里遇到的这个具体问题,我在网上找不到任何解决方案。

我有一个带有名为“StudentsToAdd”的ObservableCollection的ViewModel。此集合绑定到ItemsControl。在ItemsControl之外,我有一个Button,它绑定了ViewModel中的“AddCommand”命令。我的XAML的相关摘录如下:

extern "C"

+和 - 按钮将添加或删除StudentsToAdd集合中的学生。 “AddCommand”将所有条目从StudentsToAdd移动到另一个名为“Students”的集合中。

现在我无法工作的是:只要修改了StudentsToAdd中的学生(在任何击键之后:<StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <Button Content="Add" Command="{Binding AddCommand}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/> <Button Content="+" Command="{Binding AddToAddListCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="3,0,3,0" Margin="50,0,0,0"/> <Button Content="-" Command="{Binding RemoveFromAddListCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="5,0,5,0" Margin="5,0,0,0"/> </StackPanel> <ItemsControl x:Name="AddList" ItemsSource="{Binding Path=StudentsToAdd}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBox Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100" Margin="0 5 3 5"> <TextBox.InputBindings> <KeyBinding Command="{Binding ElementName=AddList, Path=DataContext.AddCommand}" Key="Return"/> </TextBox.InputBindings> </TextBox> <TextBox Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100" Margin="0 5 3 5"> <TextBox.InputBindings> <KeyBinding Command="{Binding ElementName=AddList, Path=DataContext.AddCommand}" Key="Return"/> </TextBox.InputBindings> </TextBox> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> )。我希望Add Button在ViewModel中评估AddCommand的CanExecute,以便相应地自动设置其IsEnabled属性。 ViewModel中的命令方法目前如下所示:

UpdateSourceTrigger=PropertyChanged

有没有人知道如何在不耦合部分MVVM的情况下实现这一目标?

1 个答案:

答案 0 :(得分:0)

  

有没有人知道如何在不耦合部分MVVM的情况下实现这一目标?

你的问题没有太多背景。但是,您似乎在询问如何在视图模型/模型层中完成此操作,而不涉及视图层。至少,那就是你应该要求的。

如果是这样,它应该相对简单,假设您未显示的代码是合理编写的。也就是说,由于您的CanAdd()方法取决于Student对象的属性值,因此您需要订阅Student.PropertyChanged事件,并随时提升ICommand.CanExecuteChanged事件任何Student个对象'PropertyChanged事件都会被引发。

对于它的价值,我还会在Student类中封装“可以添加”逻辑,而不是ViewModel类。将该状态公开为ViewModel类可以检查的单个属性。这将涉及以下几点:

  1. 您的Student类似乎更合理地放置代码,以确定是否可以将类添加到Students列表中,并且
  2. ViewModel类可以检查以确保它是正在更改的属性,因此每次{Student对象都没有费心去检查所有其他Student对象1}}属性更改,每个Student对象将有效地缓存“可以添加”值,以便检查所有其他Student对象的工作是简单的属性检索,而不是每次都要重新评估状态。
  3. 我假设您已经了解如何举起ICommand.CanExecuteChanged活动,但如果没有,这里有几篇帖子可以帮助您:

    CanExecuteChanged event of ICommand
    ICommand CanExecuteChanged not updating

    (您将看到有两个基本策略:在ICommand对象中实现明确引发ICommand.CanExecuteChanged事件的内容,或调用InputManager.InvalidateRequerySuggested()强制输入管理器调用它知道的所有CanExecute()方法。恕我直言,后者是一种相当重量级且不太理想的方法,因此我建议使用ICommand.CanExecuteChanged事件。)