0

我在我的ViewAXML)中定义了一个按钮,代码如下:

<Button Content="Fetch Data" Command="{Binding readInventoryFilesCommand}" CommandParameter="{Binding Path=Text, ElementName=browseFolderTextBox}" Name="button1" />

ListView该按钮按预期工作,但如果 a已填充元素,我希望启用/禁用它。

  • 如果 listView 中没有元素 --> ButtonIsEnabled设置为false
  • 如果 listView 中有元素 --> ButtonIsEnabled设置为true

我试图玩弄,IsEnabled="{Binding ...但我没有进入code completionVisual Studio C# Express很难猜出替代方案。

该命令如下所示:

internal class ReadInventoryFilesCommand : ICommand
{
    public ReadInventoryFilesCommand(ResourceViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    private ResourceViewModel _viewModel;

    #region ICommand Members

    event EventHandler ICommand.CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }

    bool ICommand.CanExecute(object parameter)
    {
        return _viewModel.CanUpdate;
    }

    void ICommand.Execute(object parameter)
    {
        _viewModel.ReadInventroyFiles(parameter.ToString());
    }
    #endregion
}

编辑 这是 Bobs 建议后的当前代码:

internal class ReadInventoryFilesCommand : ICommand
    {
        public ReadInventoryFilesCommand(ResourceViewModel viewModel)
        {
            _viewModel = viewModel;
            _viewModel.PropertyChanged+= (s,e) => { 
                if (e.PropertyName == "CanUpdate") RaiseCanExecuteChanged();
            };
        }

        private ResourceViewModel _viewModel;

        event EventHandler ICommand.CanExecuteChanged;

        bool ICommand.CanExecute(object parameter)
        {
            return _viewModel.CanUpdate;
        }

        void ICommand.Execute(object parameter)
        {
            _viewModel.ReadInventroyFiles(parameter.ToString());
        }

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

它会产生以下错误:

An explicit interface implementation of an event must use event accessor syntax 
4

4 回答 4

2

当它可以执行时,您需要从您的命令中引发 CanExecuteChanged 事件。

编辑

正如评论中提到的 gehho ,使用 ICommand 接口时不需要绑定到按钮的 IsEnabled 属性,因为 Button 将使用该CanExecute函数来确定它是否已启用。

但是,您需要引发CanExecuteChanged事件以通知命令该值已更改。

结束编辑

假设_viewModel实现INotifyPropertyChanged您可以在视图模型更改时挂钩并在命令上引发更改的事件:

我提供了两个版本,一个使用 ICommand 的显式实现,另一个仅实现没有显式 ICommand 前缀的属性和方法。两者都应该工作。我通常会使用版本 2,除非在具有特定要求的方法上存在冲突。

编辑版本 1 - 显式实现

internal class ReadInventoryFilesCommand : ICommand
{
  public ReadInventoryFilesCommand(ResourceViewModel viewModel)
  {
    _viewModel = viewModel;
    _viewModel.PropertyChanged+= (s,e) => { 
                                  if (e.PropertyName == "CanUpdate") RaiseCanExecuteChanged();
                                 };
  }

  event EventHandler ICommand.CanExecuteChanged { add; remove; }

  private ResourceViewModel _viewModel;

  bool ICommand.CanExecute(object parameter)
  {
    return _viewModel.CanUpdate;
  }

  void ICommand.Execute(object parameter)
  {
    _viewModel.ReadInventroyFiles(parameter.ToString());
  }

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

编辑版本 2

internal class ReadInventoryFilesCommand : ICommand
{
  public ReadInventoryFilesCommand(ResourceViewModel viewModel)
  {
    _viewModel = viewModel;
    _viewModel.PropertyChanged+= (s,e) => { 
                                  if (e.PropertyName == "CanUpdate") RaiseCanExecuteChanged();
                                 };
  }

  public event EventHandler CanExecuteChanged;

  private ResourceViewModel _viewModel;

  public bool CanExecute(object parameter)
  {
    return _viewModel.CanUpdate;
  }

  public void Execute(object parameter)
  {
    _viewModel.ReadInventroyFiles(parameter.ToString());
  }

  void RaiseCanExecuteChanged() {
    var handler = this.CanExecuteChanged;
    if (handler != null) handler(this,EventArgs.Empty);
  }
}
于 2013-10-21T08:02:03.963 回答
1

我认为您可以将绑定与转换器一起使用:代码 Windows1.xaml:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300"
        xmlns:converters="clr-namespace:WpfApplication1"
        >
    <Window.Resources>
        <converters:CoverterItemsSource2Enabled x:Key="converter" />
    </Window.Resources>
    <Grid Margin="0,0,-256,0">
        <ListView x:Name="listView" HorizontalAlignment="Left" Margin="10,10,0,10" VerticalAlignment="Stretch" Width="196">
            <ListView.View>
                <GridView>
                    <GridViewColumn/>
                </GridView>
            </ListView.View>
        </ListView>
        <Button Content="Button" HorizontalAlignment="Left" Margin="211,10,0,0" VerticalAlignment="Top" IsEnabled="{Binding Path=Items, ElementName=listView, Converter={StaticResource converter} }" Width="75"/>

    </Grid>
</Window>

代码转换器:

namespace WpfApplication1
{
    class CoverterItemsSource2Enabled : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return false;
            if(value is ItemCollection)
            {
                if ((value as ItemCollection).Count > 0)
                    return true;
            }
            return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
于 2013-10-21T07:47:10.817 回答
1

IsEnabled这是绑定到时的默认行为Items.Count

例如

<ListView x:Name="RulesList" />
<Button IsEnabled="{Binding Items.Count, ElementName=RulesList}" />

在此示例中,当它没有项目Button时将被禁用,ListView当它有 1 个或多个项目时将被启用。

于 2016-03-31T17:24:57.630 回答
0

你在说这个吗?:

private void ListView1_SourceUpdated(object sender, DataTransferEventArgs e)
 {
   Button1.IsEnabled==(ListView1.Items.Count>0);
 }
于 2013-10-21T07:39:06.827 回答