WPF / Silverlight: как сделать вызов кнопки ICommand.CanExecute при изменении параметра команды? - PullRequest
1 голос
/ 19 июля 2010

Как сделать вызов кнопки ICommand.CanExecute при изменении параметра команды?

Это мой текущий XAML.

<Button Content="Delete" Command="{Binding DeleteItemCommand}" CommandParameter="{Binding SelectedItem, ElementName=DaGrid}" />

РЕДАКТИРОВАТЬ Появляетсяэто только проблема в WPF.

Ответы [ 3 ]

4 голосов
/ 19 июля 2010

Я не уверен, что вы делаете неправильно, но вот пример того, как Button управляется как BindingParameter, так и флагом CanExecute. Возможно, ваш параметр привязки не является DependencyProperty, и поэтому, когда он изменяется, кнопка не получает уведомления.

<UserControl x:Class="SilverlightICommandTest.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:ct="clr-namespace:SilverlightICommandTest"
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
    <ct:TestModel x:Key="Model" />
</UserControl.Resources>

<StackPanel x:Name="LayoutRoot" Orientation="Vertical" Background="White" DataContext="{StaticResource Model}">
    <CheckBox Content="Enable" IsChecked="{Binding TestCmd.CanDoCommand, Mode=TwoWay}" />
    <Grid HorizontalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding ElementName=testSlider, Path=Value}" Width="40" Grid.Column="0" />
        <Slider Name="testSlider" Minimum="0" Maximum="100" SmallChange="1" Grid.Column="1" />
    </Grid>
    <Button Command="{Binding TestCmd}" CommandParameter="{Binding ElementName=testSlider, Path=Value}" Content="Do Something" />
</StackPanel>
</UserControl>

И файл кода:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace SilverlightICommandTest
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }

    public class TestModel : DependencyObject
    {
        TestCommand _testCmd = new TestCommand();

        public TestCommand TestCmd { get { return _testCmd; } }

        public TestModel()
        {
        }
    }

    public class TestCommand : DependencyObject, ICommand
    {
        public static readonly DependencyProperty CanDoCommandProperty = DependencyProperty.Register("CanDoCommand", typeof(Boolean), typeof(TestCommand), new PropertyMetadata(false, new PropertyChangedCallback(CanDoCommandChanged)));

        public Boolean CanDoCommand
        {
            get { return (Boolean)GetValue(CanDoCommandProperty); }
            set { SetValue(CanDoCommandProperty, value); }
        }

        public event EventHandler CanExecuteChanged;

        public TestCommand()
        {
        }

        public Boolean CanExecute(Object parameter)
        {
            return this.CanDoCommand && (((Int32)(Double)parameter) % 2 == 0);
        }

        public void Execute(Object parameter)
        {
            MessageBox.Show("Oh Hai!");
        }

        private void OnCanDoCommandChanged(DependencyPropertyChangedEventArgs args)
        {
            if (this.CanExecuteChanged != null)
            {
                this.CanExecuteChanged(this, new EventArgs());
            }
        }

        private static void CanDoCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((TestCommand)sender).OnCanDoCommandChanged(args);
        }
    }
}

В будущем я рекомендую сначала немного больше изучить шаблон (http://www.silverlightshow.net/items/Model-View-ViewModel-in-Silverlight.aspx),, и если вы все еще не можете его выяснить, опубликуйте больше своего исходного кода.

1 голос
/ 19 июля 2010

Вам необходимо позвонить CommandManager.InvalidateRequerySuggested, чтобы переоценить CanExecute.Обратите внимание, что он пересмотрит его для всех команд, а не только для той, которую вы хотите ...

1 голос
/ 19 июля 2010

Странно. Обычно OnCommandParameterChanged вызывает UpdateCanExecute (оба внутренних метода). Работает ли Binding to CommandParameter должным образом?

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