[UWP / MVVM] Кнопка включения / выключения в столбце шаблона данных RadDataGrid, к которым привязаны команды при определенных условиях - PullRequest
0 голосов
/ 18 сентября 2018

Я установил свойство bool и связал его с IsEnabled в xaml, но метод ICommand CanExecute переопределяет IsEnabled в xaml, поэтому мое свойство bool неэффективно.

Когда я определяю условия в методе CanExecute в модели представления, он либо отключает все кнопки, к которым привязан метод, либо включает все из них.

Это сетка, которая отображает 3 разные кнопки для каждой строки, и каждая кнопка переходит на новый экран xaml. Если в строке нет данных для конкретного условия, кнопка включена, то эту кнопку необходимо отключить.

Как мне настроить это так, чтобы кнопки отключались при определенных условиях?

Пользовательская команда:

public class CustomCommand : ICommand
{

    private Action<object> execute;
    private Predicate<object> canExecute;
    public CustomCommand(Action<object> execute, Predicate<object> canExecute)
    {
        this.execute = execute;
        this.canExecute = canExecute;

    }

    public event EventHandler CanExecuteChanged
    {
        add
        {

        }
        remove
        {

        }
    }

    public bool CanExecute(object parameter)
    {
        //throw new NotImplementedException();
        bool b = canExecute == null ? true : canExecute(parameter);
        return b;
    }

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

xaml

<DataTemplate>
                                <Button Command="{Binding Source={StaticResource VM},
                                Path=Command}" CommandParameter="{Binding}" >
                                    <SymbolIcon Symbol="Edit" Foreground="AliceBlue" />
                                </Button>
</DataTemplate>

CanExecute в VM

 private bool CanGetDetails(object obj)
    {
        return true;
    }

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Я думаю, что вы можете выбрать много кода из RelayCommand MVVMLight. Попробуйте изменить ваше событие на

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (canExecute != null)
            {
                CommandManager.RequerySuggested += value;
            }
        }

        remove
        {
            if (canExecute != null)
            {
                CommandManager.RequerySuggested -= value;
            }
        }
    }

и добавьте также функцию

    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

Затем, независимо от того, что вы указали в качестве предиката в команде, в логическом установщике предиката выполните:

SomeCustomCommand.RaiseCanExecuteChanged()

Надеюсь, я помог.

0 голосов
/ 18 сентября 2018

Вы всегда можете сделать свой условный оператор в функции CanExecute вашей пользовательской команды, вам не нужно связывать свойство IsEnabled с вашей кнопкой, связанной с командой.Вот пример реализации, надеюсь, это поможет.

Пользовательская команда:

public class CustomCommand<T> : ICommand
{
    private readonly Action<T> _action;
    private readonly Predicate<T> _canExecute;

    public CustomCommand(Action<T> action, Predicate<T> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

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

    public void Execute(object parameter)
    {
        _action((T)parameter);
    }

    public event EventHandler CanExecuteChanged;
}

Как вы можете видеть здесь, я создал объект, который реализует интерфейс ICommand, эта пользовательская команда принимает универсальный типпараметр, который используется для оценки условия (CanExecute: указывает, включать или отключать команду (в пользовательском интерфейсе, кнопка), обычно используется для проверки разрешений и других определенных условий), этот параметр также используется для выполнения действия (Выполнить: фактическая логика / действие, которое должно быть выполнено), командный конструктор принимает параметры делегата, которые содержат сигнатуры для этих двух методов, вызывающая сторона может выбрать лямбда или стандартные методы для заполнения этих параметров.

Образец ViewModel:

public class ViewModel1: INotifyPropertyChanged
    {
        public ViewModel1()
        {
            // Test Data.
            Items = new ObservableCollection<ItemViewModel>
            {
                new ItemViewModel{ Code = "001", Description = "Paint" },
                new ItemViewModel{ Code = "002", Description = "Brush" },
                new ItemViewModel{ Code = "003", Description = "" }
            };

            EditCommand = new CustomCommand<ItemViewModel>(Edit, CanEdit);
        }

        public CustomCommand<ItemViewModel> EditCommand { get; }

        private bool CanEdit(ItemViewModel item)
        {
            return item?.Description != string.Empty;
        }

        private void Edit(ItemViewModel item)
        {
            Debug.WriteLine("Selected Item: {0} - {1}", item.Code, item.Description);
        }

        private ObservableCollection<ItemViewModel> _items { get; set; }

        public ObservableCollection<ItemViewModel> Items
        {
            get => _items;
            set
            {
                _items = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

XAML:

<Page x:Name="root"
    x:Class="App1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:vms="using:App1.ViewModels"
      mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    d:DesignHeight="450" d:DesignWidth="800">
    <Page.DataContext>
        <vms:ViewModel1 x:Name="Model"/>
    </Page.DataContext>
    <Grid>
        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="0 0 0 15">
                        <TextBlock Text="{Binding Code}" />
                        <TextBlock Text="{Binding Description}" />
                        <Button Content="Edit" Command="{Binding DataContext.EditCommand, ElementName=root}" CommandParameter="{Binding}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Page>

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...