禁用ListView的DataTemplate

时间:2015-07-28 19:17:42

标签: c# wpf listview button datatemplate

所以,让我们说我有一个简单的小WPF应用程序,如下所示:

-------------------------------
Amount Left: 1,000
[Subtract 1]
[Subtract 5]
[Subtract 15]
[Subtract 30]
-------------------------------

"剩余金额:"和" 1,000"是独立的TextBlocks。 "减去x"是ListView内部的所有按钮,位于DataTemplate中。每次单击一个按钮,都会从1,000中减去该按钮的数量。所有这些我都在工作。

这是我无法弄清楚的。当剩余数量低于30时,最后一个按钮需要被禁用。当金额低于15时,倒数第二个按钮将被禁用。等等,直到剩余数量为零并且所有按钮都被禁用。我无法弄清楚如何禁用按钮。

我在这里给出的这个例子不是完全我想要做的事情,但它是一个非常简化的例子,可以使这篇文章更短,简单。在本质上,这就是我现在所拥有的。

XAML:

<DockPanel>
    <TextBlock Text="Amount Left:" />
    <TextBlock x:Name="AmountLeft" Text="1,000.00" />
</DockPanel>
<DockPanel>
    <ListBox x:Name="AuthorListBox">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Button x:Name="SubButtom" Content="{Binding SubtractAmount}" Click="clickSubtract" />
            <DataTemplate>
    </ListBox>
</DockPanel>

XAML.cs

    private void clickSubtract(object sender, RoutedEventArgs e)
    {
        Button button = sender as Button;
         Int32 SubtractAmount = ((Data.AppInformation)button.DataContext).SubtractAmount;  // This is the amount to be subtracted
        // logic to update the amount remaining.  This works.
        //  What I need to figure out is how to disable the buttons
    }

3 个答案:

答案 0 :(得分:1)

我会继续创建一个Converter并绑定按钮的IsEnabled属性。传递值并做逻辑。

命名空间

System.Windows.Data

System.Globalization

CODE

 public class IsEnabledConverter : IValueConverter
 {
  public object Convert(object value, Type targetType, 
    object parameter, CultureInfo culture)
  {
    // Do the logic
  }

    public object ConvertBack(object value, Type targetType, 
    object parameter, CultureInfo culture)
   {
    // Do the Logic
   }
}

XAML

像这样添加resurce

<Window.Resources>
    <local:IsEnabledConverter  x:Key="converter" />
</Window.Resources>

<Button x:Name="SubButtom" IsEnabled="{Binding Value, Converter=   {StaticResource  converter}}" Content="{Binding SubtractAmount}" Click="clickSubtract" />

您可以从以下链接了解转换器

http://wpftutorial.net/ValueConverters.html 

使用Converter构建类时,所有Xaml错误都将消失。

答案 1 :(得分:0)

您可以使用MVVM来完成按钮IsEnabled的{​​{1}}属性。使用这种方法,您不需要任何&#39;代码&#39;因为您目前使用了点击事件处理程序。

<强>的Xaml:

ViewModels

<强> Xaml.cs:

<Grid>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Amount Left:" />
            <TextBlock Text="{Binding CurrentAmount}" />
        </StackPanel>
        <ListBox ItemsSource="{Binding Buttons}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Button Command="{Binding SubtractCommand}" Width="200" Height="75" x:Name="SubButtom" Content="{Binding SubtractAmount}"  IsEnabled="{Binding IsEnabled}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Grid>

我们希望主public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new ViewModel(); } } 的列表中包含ViewModel Button

<强> ButtonViewModel.cs:

ViewModels

现在是主namespace WpfApplication1 { public class ButtonViewModel : INotifyPropertyChanged { private bool _isEnabled; private ViewModel _viewModel; public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; OnPropertyChanged(); } } public int SubtractAmount { get; set; } public ICommand SubtractCommand { get; private set; } public ButtonViewModel(ViewModel viewModel) { _viewModel = viewModel; IsEnabled = true; SubtractCommand = new CommandHandler(() => { _viewModel.CurrentAmount -= SubtractAmount; }, true); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class CommandHandler : ICommand { private readonly Action _action; private readonly bool _canExecute; public CommandHandler(Action action, bool canExecute) { _action = action; _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { _action(); } } }

<强> ViewModel.cs:

ViewModel

如您所见,每个Button namespace WpfApplication1 { public class ViewModel : INotifyPropertyChanged { private int _currentAmount; public int CurrentAmount { get { return _currentAmount; } set { _currentAmount = value; OnPropertyChanged(); if (Buttons != null) { foreach (var button in Buttons) { if ((value - button.SubtractAmount) <= 0) { button.IsEnabled = false; } } } } } public List<ButtonViewModel> Buttons { get; private set; } public ViewModel() { CurrentAmount = 1000; Buttons = new List<ButtonViewModel> { new ButtonViewModel(this) { SubtractAmount = 1 }, new ButtonViewModel(this) { SubtractAmount = 5 }, new ButtonViewModel(this) { SubtractAmount = 15 }, new ButtonViewModel(this) { SubtractAmount = 30 } }; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } 将使用Command(对于单击事件的首选方法)递减ViewModel。每当更改CurrentAmount时,主CurrentAmount将完成一些简单的逻辑,这将禁用相关按钮。

这是经过测试和运作的。如果您有任何问题,请告诉我。

答案 2 :(得分:0)

您最好的选择是在viewmodel上使用命令而不是click事件处理程序:

public ICommand SubtractCommand = new DelegateCommand<int>(Subtract, i => i <= AmountLeft);

private void Subtract(int amount)
{
    AmountLeft = AmountLeft - amount;
}

XAML:

<ListBox x:Name="AuthorListBox">
    <ListBox.ItemTemplate>
        <DataTemplate>
                <Button x:Name="SubButtom" Content="{Binding SubtractAmount}"
                        Command="{Binding SubtractCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                        CommandParameter="{Binding SubtractAmount}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>