根据MVVM中的复选框列表选择启用WPF按钮

本文关键字:选择 启用 WPF 按钮 列表 复选框 MVVM 根据 | 更新日期: 2023-09-27 17:59:00

我有一个复选框列表项和一个提交按钮。提交按钮最初需要禁用。该按钮需要通过选择单个复选框或多个复选框来启用。我在XAML中添加了以下代码,后端代码需要有一个使用MVVM的视图模型。

XAML。。

<ListBox Grid.Row="1" BorderThickness="0" Background="Transparent" Name="list" ItemsSource="{Binding Items}" Margin="10 5 20 0" SelectionMode="Extended">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox Name="check" IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="5 5 0 10" VerticalAlignment="Center" />
                                <ContentPresenter Content="{Binding Value}" Margin="5 5 0 10"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
<Button Grid.Row="2" Click="Button_Click" HorizontalAlignment="Right" Height="25" Width="60" Margin="0,0,30,0" IsEnabled="{Binding Path=IsButtonEnabled}">                    <TextBlock>Submit</TextBlock> </Button>

那么视图模型如何使用OnPropertyChanged()实现呢。

根据MVVM中的复选框列表选择启用WPF按钮

您需要注册到视图模型中每个项的所有PropertyChanged事件并聚合结果。例如:

class ViewModel
{
    public ViewModel()
    {
        Items = new ObservableCollection<Item>();
        PropertyChangedEventHandler propertyChangedHandler = (o, e) =>
        {
            if (e.PropertyName == nameof(Item.IsChecked))
                OnPropertyChanged(nameof(IsButtonEnabled));
        };
        Items.CollectionChanged += (o, e) =>
        {
            if (e.OldItems != null)
                foreach (var item in e.OldItems.OfType<INotifyPropertyChanged>())
                    item.PropertyChanged -= propertyChangedHandler;
            if (e.NewItems != null)
                foreach (var item in e.NewItems.OfType<INotifyPropertyChanged>())
                    item.PropertyChanged += propertyChangedHandler;
        };
    }
    public ObservableCollection<Item> Items { get; }
    public bool IsButtonEnabled => Items.Any(i => i.IsChecked);
}

另一个需要考虑的选项是使用ReactiveUI。