【问题标题】:How to disable a button if no items are selected in a ListView如果在 ListView 中未选择任何项目,如何禁用按钮
【发布时间】:2011-11-17 18:03:47
【问题描述】:

我有一个 ListView 包含在用户控件中我想在用户控件中未选择任何项目时禁用按钮,这是正确的方法吗?到目前为止,它并没有禁用,它只是一直保持启用。 我已经包含了 xaml 代码。

searchAccountUserControl 是 xaml 中的 UserControl 名称属性。 而 AccountListView 是 userControl xaml 中的ListView name 属性。

<Button Content="Debit" IsEnabled="true" HorizontalAlignment="Left" Margin="18,175,0,0" Name="DebitButton" Width="128" Grid.Column="1" Height="32" VerticalAlignment="Top" Click="DebitButton_Click">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=searchAccountUserControl.AccountListView, Path=SelectedValue}" Value="{x:Null}" >
                        <Setter Property="Button.IsEnabled" Value="false"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

谢谢。

终于用上了:

在我的视图模型中:

private bool _isSelected;
public bool IsSelected { get { return _isSelected; } 
set { _isSelected = _account.View.CurrentItem != null;       
PropertyChanged.SetPropertyAndRaiseEvent(this, ref _isSelected, value,  
ReflectionUtility.GetPropertyName(() => IsSelected)); } } 

然后在 xaml 中使用 isEnabled = "{Binding Path=IsSelected}"。

【问题讨论】:

  • MVVM 不只是使用绑定。它将 View 从 ViewModel 中分离出来。您是解决方案,认为它可能有效,将视图与 ViewModel 耦合。但是,嘿,如果它有效,它有效吗?

标签: c# wpf xaml listview user-controls


【解决方案1】:

这里有一些问题。

  1. Precedence,如果您在控件本身上设置IsEnabled,则样式将永远无法更改。

  2. ElementName,这是一个ElementName,不是路径,只是一个字符串,它给出了一个元素的名称。除此之外的所有内容都进入Path

  3. 样式语法,如果设置Style.TargetType,则不应使用类型前缀设置Setter.Property(尽管保留它不会破坏setter)。

顺便说一句,仅此一项就足够了:

<Button IsEnabled="{Binding SelectedItems.Count, ElementName=lv}" ...

【讨论】:

  • 好点...我完全忽略了他的纯 xaml 方法,并使用了 MVVM 讲座 + XAML/Code-Behind 组合(他已经在使用这种组合)。
  • 我的 Xaml 使用 baseWindowViewModel 而且我也在使用绑定路径。但正如我所说我不知道​​如何使用绑定来做到这一点,所以我试图找到一种使用代码背后的方法,但我宁愿用我的 ViewModel 方法保持它直截了当。
  • 所以我想我可以使用
  • @Jonathan:如果您观察优先级并修复绑定,触发器也可以工作,但如果您可以直接绑定到 ListView,您可以执行如上所示的绑定,这将导致转换count to bool: 0 selected -> false = disabled; 1 个或多个已选择 -> true = 已启用。
  • @Hb :由于 listView 在 userControl 中,我不知道是否可以直接绑定它,我不知道我所说的最好的方法是保持模式并保持代码干净。我可以做类似
【解决方案2】:

很明显,您没有使用命令 (ICommand Interface)。您应该使用它(最好是 Model-View-ViewModel 架构)。

但是,如果您想坚持使用代码隐藏和 XAML:

<ListView SelectionChanged="AccountListView_SelectionChanged" ... />

private void AccountListView_SelectionChanged(Object sender, SelectionChangedEventArgs args)
{
    DebitButton.IsEnabled = (sender != null);

    //etc ...
}

更多关于 MVVM 的信息:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

您需要将 View (UserControl) 的 DataContext 设置为您要使用的 ViewModel 的实例。然后,您可以从那里绑定到 ViewModel 上的属性,包括ICommands。您可以使用RelayCommand(参见上面的链接)或使用框架提供的命令(例如,Prism 提供了DelegateCommand)。这些命令采用 Action (Execute) 和 Func (CanExecute)。只需在 CanExecute 中提供逻辑。当然,您还必须将 ListView SelectedItem(或 SelectedValue)数据绑定到 ViewModel 上的属性,以便在 CanExecute 函数中检查它是否为空。

假设您使用RelayCommand,您不必显式调用ICommandRaiseCanExecuteChanged

public class MyViewModel : ViewModelBase //Implements INotifyPropertyChanged
{
    public MyViewModel()
    {
        DoSomethingCommand = new RelayCommand(DoSomething, CanDoSomething);
    }

    public ObservableCollection<Object> MyItems { get; set; }
    public Object SelectedItem { get; set; }

    public RelayCommand DoSomethingCommand { get; set; }


    public void DoSomething() { }

    public Boolean CanDoSomething() { return (SelectedItem != null); }
}
<ListView ItemsSource="{Binding MyItems}" SelectedItem="{Binding SelectedItem}" ... />
<Button Command="{Binding DoSomethingCommand}" ... />

【讨论】:

  • 我实际上使用的是模型视图视图模型架构。我只是不知道该怎么做,所以在互联网上搜索了一个线索。
  • 你使用什么框架(如果有的话)?并且使用事件不是 MVVM ...绑定(包括命令绑定)是 MVVM。
  • 是的,我知道我在谈论代码的其他部分。使用 viewModel 和 {Binding Path=... Converter 等...}
  • @Jonathan:我认为您没有使用 MVVM 的原因是您已命名 XAML 控件(不必要)并且您的按钮上有一个 Click 事件(不必要)。
  • 好吧,是的,我们所有的 viewModel 都实现了 INotifyPropertyChanged 我猜我们只是没有使用 RelayCommands。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
相关资源
最近更新 更多