Have a command with "CanXXXX" while listening to several properties

I am performing a UserControlwizard that can display (with WPF + Prism).

For this, I have two controls: Wizardand WizardPage.

I want me to finish with such things

<Wizard>
    <WizardPage CanGoToNext="{Binding SomePropertySayingThatThisPaneIsOk}">
        <TextBlock>Page one</TextBlock>
    </WizardPage>
    <WizardPage CanGoToNext="{Binding SomePropertySayingThatThisPaneIsOk}" CanGoToPrevious="False">
        <TextBlock>Page Four</TextBlock>
    </WizardPage>
    <WizardPage CanGoToNext="{Binding SomePropertySayingThatThisPaneIsOk}" CanGoToPrevious="True">
        <TextBlock>Page Three</TextBlock>
    </WizardPage>
</Wizard>

I am now stuck in a team in the UserControl wizard.

I will have 3 Buttons:

  • Previous
  • Further
  • Cancel

On which I would like to bind some UserControl commands.

A problem is a condition for updating if a button command can be executed.

In my case, I would like to:

//PseudoCode
CurrentPage != FirstPage
&& CurrentPage.CanGoToPrevious

But I don’t see how to do it DelegateCommandand ask them to check its state again when the dependency property changes CurrentPage.CanGoToPrevious?

+4
source share
1

, WPF CommandManager.RequerySknown event CommandManager.InvalidateRequerySposed , - CanExecuted. , , ( ). , :

public class DelegateCommand : ICommand {
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public DelegateCommand(Action<object> execute, Predicate<object> canExecute) {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) {
        return _canExecute(parameter);
    }

    public void Execute(object parameter) {
        _execute(parameter);
    }

    public void RefreshCanExecute() {
        var handler = CanExecuteChanged;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

    public event EventHandler CanExecuteChanged;
}

, - , DelegateCommand.RefreshCanExecute:

    public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        this.BtnCommand = new DelegateCommand(_ => {
            MessageBox.Show("test");
        }, _ => CheckCanExecute());
        this.DataContext = this;            
    }

    private bool CheckCanExecute() {
        return SomeProperty == 1;
    }

    public int SomeProperty
    {
        get { return (int) GetValue(SomePropertyProperty); }
        set { SetValue(SomePropertyProperty, value); }
    }

    public static readonly DependencyProperty SomePropertyProperty =
        DependencyProperty.Register("SomeProperty", typeof(int), typeof(MainWindow), new PropertyMetadata(0, OnSomePropertyChanged));

    private static void OnSomePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        ((MainWindow) d).BtnCommand.RefreshCanExecute();
    }

    public DelegateCommand BtnCommand { get; private set; }      
}

Xaml:

<Button Content="test" Command="{Binding BtnCommand}" />

. , , , , . : :

public class AndConverter : IMultiValueConverter {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if (values.Length == 0) return false;
        return values.All(c => c != null && c != DependencyProperty.UnsetValue && (bool) c);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}

( ) . xaml IsEnabled :

<Window.Resources>
    <wpf:AndConverter x:Key="and" />
</Window.Resources>
<Button Content="test" Command="{Binding BtnCommand}">
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource and}">
            <Binding Path="IsFirstPage" />
            <Binding Path="CanGoToPrevious" />
        </MultiBinding>
    </Button.IsEnabled>
</Button>

, IsEnabled .

+3

Source: https://habr.com/ru/post/1605950/


All Articles