问题
I have a ListBox control populated with several ListBox items. Each item contains a "Proceed" button and a "Postpone" button. I would like to hide that ListBox item (presented as a row in my case) once the "Postpone" button is clicked. The code I have currently doesn't seem to have any effect.
XAML:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding PostponeClicked}" Value="1">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
C#:
private void PostponeThirdPartyUpdatesButton_Click(object sender, RoutedEventArgs e)
{
DataTrigger d = new DataTrigger();
d.Binding = new Binding("PostponeClicked");
d.Value = 1;
var context = ((FrameworkElement)sender).DataContext as Tuple<RegScan_ThirdParty.InstalledApplicationFromRegistryScan, RegScan_ThirdParty.ManifestRequiredApplication, RegScan_ThirdParty.RequiredApplicationState>;
Button ThirdPartyPostponeButton = sender as Button;
ThirdPartyPostponeButton.IsEnabled = false;
if (context != null)
{
RegScan_ThirdParty.registryApplicationPostponeWorkflow(context);
}
ThirdPartyPostponeButton.IsEnabled = true;
}
回答1:
I had to address the same thing once. Each item in your list box should be an object. We'll call it MyObject
for now, since I have no idea what your object type is. In the MyObject class, you'll put your Proceed and Postpone commands.
//ViewModelBase implements INotifyPropertyChanged, which allows us to call RaisePropertyChanged, and have the UI update
class MyObject : ViewModelBase
{
private bool isNotPostponed = true;
public bool IsNotPostponed
{
get { return isNotPostponed; }
set
{
isNotPostponed = value;
RaisePropertyChanged("IsNotPostponed");
}
}
private Command postponeCommand;
public Command PostponeCommand
{
get
{
if (postponeCommand == null)
postponeCommand = new Command(PostponeCommand);
return postponeCommand;
}
}
private void Postpone(object x)
{
IsNotPostponed = false;
}
//similar code for Proceed Command
}
Then in the viewmodel of the view that displays the listBox, create a List that you can bind to your listbox (or whatever collection you want to use). I called it MyObjectsList in the XAML below. (I'm not showing the ViewModel code where this object lives, but I assume you have code for binding to the ListBox.) Then in your ItemsControl.ItemTemplate, bind to each MyObject in your List.
<ItemsControl ItemsSource="{Binding MyObjectsList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<BooleanToVisibilityConverter x:Key="boolToVis"/>
</DataTemplate.Resources>
<StackPanel Visibility="{Binding IsNotPostponed, Converter={StaticResource boolToVis}}">
<Button Command="{Binding PostponeCommand}" Content="Postpone"/>
<Button Command="{Binding ProceedCommand}" Content="Proceed"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
When Postpone is clicked, the command will execute Postpone(), which will set IsNotPostponed to false. On setting IsNotPostponed to false, RaisePropertyChanged tells the UI that IsNotPostponed changed (you need to implement the INotifyPropertyChanged interface.) Lastly, when the UI gets the change notification, it converts the bool to a Visibility. True => Visible, False => Collapsed.
来源:https://stackoverflow.com/questions/22524070/hiding-a-listbox-item-in-wpf