复选框启用禁用按钮检查/取消选中wpf mvvm

时间:2010-08-10 05:27:57

标签: wpf silverlight mvvm

我在窗口上有一个复选框列表,指定了一些要订购的项目。我需要在窗口加载时首先禁用“订购”按钮,并在选择/检查某些项目(复选框)后启用它,反之亦然。我绑定了复选框的IsChecked属性。

修改从OP评论中导入: -

ItemsControl中只有一个复选框。我已将ItemsControl的ItemsSource绑定到List。这样我们就可以根据列表中的项目显示多个复选框。

以下是代码:

<ItemsControl ItemsSource="{Binding FavoriteItems}" Margin="80,0">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Grid>
        <StackPanel>
          <Grid>
            <CheckBox IsChecked="{Binding IsHouseholdSelected}" Content="{Binding SubCategoryName}" Grid.ColumnSpan="1" FontFamily="Calibri" FontWeight="Bold" />
          </Grid>
        </StackPanel>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>

2 个答案:

答案 0 :(得分:1)

以下示例代码可以帮助您解决问题。基本上,这里的关键是我让列表中的Items隐含地通知其父ViewModel的Command对象,以便每次IsChecked属性更改时引发CanExecuteChanged事件。 (另外,我在这里使用“DelegateCommand”,这与“RelayCommand”相同。)

的ViewModels:

    public class ViewModel : INotifyPropertyChanged
    {
        public DelegateCommand MyCommand { get; set; }

        private ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();
        public ObservableCollection<Item> Items
        {
            get { return this.items; }
        }

        public ViewModel()
        {
            this.items.Add(new ItemViewModel(this) { IsChecked = false, Text = "Item 1" });
            this.items.Add(new ItemViewModel(this) { IsChecked = false, Text = "Item 2" });
            this.items.Add(new ItemViewModel(this) { IsChecked = false, Text = "Item 3" });

            this.MyCommand = new DelegateCommand(this.CanExecute, this.Execute);
        }

        public void Execute(object parameter)
        {
            MessageBox.Show("Executed");
        }

        public bool CanExecute(object parameter)
        {
            return (this.items.Count == this.items.Count((x) => x.IsChecked));
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        #endregion
    }

    public class ItemViewModel
    {
        private ViewModel parent;
        private bool isChecked;

        public string Text { get; set; }

        public bool IsChecked 
        {
            get { return this.isChecked; }
            set
            {
                this.isChecked = value;

                if (this.parent.MyCommand != null)
                    this.parent.MyCommand.OnCanExecuteChanged(null);
            }
        }

        public Item(ViewModel parent)
        {
            this.parent = parent;
        }
    }

查看:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>

    <DockPanel>
        <Button DockPanel.Dock="Bottom" Command="{Binding MyCommand}">Test</Button>

        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Text}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>

</Window>

答案 1 :(得分:0)

将命令绑定到按钮并实现CanExecute方法以检查复选框的状态,并启用或禁用该按钮,并使用Execute方法调用按钮上所需的功能。

MVVM RelayCommand

CanExecute on MSDN

编辑:这是一些如何实现RelayCommand的源代码。可以在上面提供的第一个链接中找到RelayCommand类。我假设您知道如何将DataContext连接到ViewModel实现。

<StackPanel>
    <CheckBox Name="MyCheckBox" Content="Some CheckBox" 
              IsChecked="{Binding MyCheckBoxChecked}"/>
    <Button Content="Click me" Command="{Binding MyCommand}"/>
</StackPanel>

public class OrderViewModel
{
    private RelayCommand MyRelayCommand;

    public OrderViewModel()
    {
        MyRelayCommand = new RelayCommand(Execute, CanExecute);
        MyCheckBoxChecked = false;
    }

    public RelayCommand MyCommand
    {
        get { return MyRelayCommand; }
    }

    public bool MyCheckBoxChecked { get; set; }

    private bool CanExecute(object o)
    {
         // Here I'm just checking the property we've bound to but you can put
         // anything in here that will return a bool, including a check of any/all
         // of the checkboxes you may need to check 
         return MyCheckBoxChecked;
    }

    private void Execute(object o)
    {
        Console.WriteLine(@"Executing ...");
    }
}