Displaying Content only when ListViewItem is Selected

只谈情不闲聊 提交于 2019-12-04 16:44:28
Zenuka

[Old useless code]


EDIT: Well I didn't read the question good enough but this should do the trick: Replace the button in your DataTemplate with this:

<Button Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Center"
        Name="view" Click="viewClicked_Click"
        Content="View">
 <Button.Style>
  <Style TargetType="{x:Type Button}">
   <Setter Property="Visibility" Value="Collapsed"/>
   <Style.Triggers>
    <DataTrigger Binding="{Binding 
                           RelativeSource={RelativeSource Mode=FindAncestor,
                           AncestorType={x:Type ListBoxItem}},Path=IsSelected}" 
                 Value="True">
     <Setter Property="Visibility" Value="Visible"/>
    </DataTrigger>
   </Style.Triggers>
  </Style>
 </Button.Style>
</Button>

What happends here is that the style sets the Visibility property to Collapsed and uses a trigger to change that. I've used a DataTrigger so you can use the {Binding ...}. With the {Binding RelativeSource={..}} you can look for an Ancestor, here we are looking for an Ancestor of type ListBoxItem.

What this does is look 'up' in the WPF tree to see if this button has a Parent object which is of type ListBoxItem if it's found it will check the IsSelected (Path=IsSelected) property if it's True and will then update the Visibility Property of the button.

I hope this explanation makes sense! :-)


EDIT2: Just for fun, the code behind way:

private Button _previousButton;
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
 if (_previousButton != null)
  _previousButton.Visibility = Visibility.Collapsed;

 // Make sure an item is selected
 if (listBox.SelectedItems.Count == 0)
  return;

 // Get the first SelectedItem (use a List<object> when 
 // the SelectionMode is set to Multiple)
 object selectedItem = listBox.SelectedItems[0];
 // Get the ListBoxItem from the ContainerGenerator
 ListBoxItem listBoxItem = listBox.ItemContainerGenerator.ContainerFromItem(selectedItem) as ListBoxItem;
 if (listBoxItem == null)
  return;

 // Find a button in the WPF Tree
 Button button = FindDescendant<Button>(listBoxItem);
 if (button == null)
  return;

 button.Visibility = Visibility.Visible;
 _previousButton = button;
}

/// <summary>
/// Finds the descendant of a dependency object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj">The obj.</param>
/// <returns></returns>
public static T FindDescendant<T>(DependencyObject obj) where T : DependencyObject
{
 // Check if this object is the specified type
 if (obj is T)
  return obj as T;

 // Check for children
 int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
 if (childrenCount < 1)
  return null;

 // First check all the children
 for (int i = 0; i < childrenCount; i++)
 {
  DependencyObject child = VisualTreeHelper.GetChild(obj, i);
  if (child is T)
   return child as T;
 }

 // Then check the childrens children
 for (int i = 0; i < childrenCount; i++)
 {
  DependencyObject child = FindDescendant<T>(VisualTreeHelper.GetChild(obj, i));
  if (child != null && child is T)
   return child as T;
 }

 return null;
}

I suggest you use the XAML Trigger "way" because it's much cleaner...

Use a converter on the selected item on the list to determine the visibility.

<Button Visibility="{Binding ElementName=lb, Path=SelectedItem, Converter={StaticResource TestConverter}}" />

Here is the value converter

public class TestConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Visibility.Collapsed;
        else
            return Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}

If you're using the MVVM pattern, you should bind your button to an ICommand such as the DelegateCommand from the MVVM Toolkit. That way the button will use the command's CanExecute() state to decide for itself whether it should be enabled or not.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!