gpt4 book ai didi

c# - WPF 触发按钮可以在 ItemsControl 之外从 ItemsControl 执行

转载 作者:行者123 更新时间:2023-12-03 10:43:01 29 4
gpt4 key购买 nike

我正在尝试从 WPF MVVM 教程中扩展应用程序作为练习。对于我在这里面临的这个特定问题,我在网上没有找到解决方案。

我有一个名为“StudentsToAdd”的带有 ObservableCollection 的 ViewModel。此集合绑定(bind)到 ItemsControl。在 ItemsControl 之外,我有一个与 ViewModel 中的“AddCommand”命令绑定(bind)的按钮。我的 XAML 的相关提取形式如下所示:

<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>

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

现在我无法开始工作的是:每当修改 StudentsToAdd 中的 Student 时(在任何击键后: UpdateSourceTrigger=PropertyChanged )。我希望添加按钮在 ViewModel 中评估 AddCommand 的 CanExecute,以便相应地自动设置其 IsEnabled 属性。 ViewModel 中的命令方法目前如下所示:
private void OnAdd()
{
foreach (Student s in StudentsToAdd)
{
Students.Add(s);
}
StudentsToAdd.Clear();
StudentsToAdd.Add(new Student { FirstName = string.Empty, LastName = string.Empty });
}

private bool CanAdd()
{
if (StudentsToAdd != null && StudentsToAdd.Count > 0)
{
return StudentsToAdd.All(x => !string.IsNullOrWhiteSpace(x.FirstName) && !string.IsNullOrWhiteSpace(x.LastName));
}
return false;
}

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

最佳答案

Does anybody know how I can achieve this without coupling parts of the MVVM?



你的问题没有太多背景。但是,您似乎在问如何完全在 View 模型/模型层内完成此操作,而不涉及 View 层。至少,这是你应该问的。

如果是这样,那应该比较简单,假设你没有展示的代码写的很合理。也就是说,由于您的 CanAdd()方法取决于 Student 的属性值对象,您需要订阅 Student.PropertyChanged事件,并提出 ICommand.CanExecuteChanged任何时间任何 Student 的事件对象' PropertyChanged引发事件。

对于它的值(value),我还将在 Student 中封装“可以添加”逻辑类,而不是 ViewModel类(class)。将该状态显示为 ViewModel 的单个属性。上课可以查。这将解决几件事:
  • 您的 Student class 似乎是放置代码的更合乎逻辑的位置,该代码确定该类是否已准备好添加到 Students 列表中, 和
  • ViewModel类可以检查以确保正在更改的是该属性,因此无需费心去检查所有其他的Student。对象每次任何Student属性更改,并且每个 Student对象将有效地缓存“可以添加”值,以便检查所有其他 Student objects 是一种简单的属性检索,而不必每次都重新评估状态。

  • 我假设您已经了解如何提高 ICommand.CanExecuteChanged事件,但如果没有,这里有一些帖子可以帮助您:

    CanExecuteChanged event of ICommand
    ICommand CanExecuteChanged not updating

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

    关于c# - WPF 触发按钮可以在 ItemsControl 之外从 ItemsControl 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45810271/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com