【问题标题】:Displaying Content only when ListViewItem is Selected仅在选择 ListViewItem 时显示内容
【发布时间】:2010-12-15 01:43:11
【问题描述】:

I have a ListBox when one of the ListBoxItems are selected I want to change the visibility of the button "View" and display it.这意味着默认状态是隐藏。

这可能吗?如果可以,我是否可以使用 XAML 中的触发器或代码隐藏来解决此问题?

XAML 片段

<ListBox Background="Transparent" 
      ItemContainerStyle="{StaticResource listBoxTemplate}" BorderThickness="0">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" VerticalAlignment="Center" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Background="Beige" Margin="10 10 10 10" 
                    HorizontalAlignment="Center" Width="500" Height="100"
                    VerticalAlignment="Stretch">
                <Grid.RowDefinitions>
                    <RowDefinition Name="TopRow" Height="50" />
                    <RowDefinition Name="BottomRow" Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Name="LeftSideMenu" Width="*"/>
                    <ColumnDefinition Name="Middle" Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Content="{Binding name}" />

                <Button Grid.Column="1" VerticalAlignment="Center" 
                    Grid.RowSpan="2" Name="view" Click="viewClicked_Click"
                    Grid.Row="0">View</Button>

                <Label Grid.Column="0" Grid.Row="1" 
                    Content="{Binding description}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

【问题讨论】:

    标签: c# wpf listbox selecteditem


    【解决方案1】:

    [旧的无用代码]


    编辑: 好吧,我没有很好地阅读这个问题,但这应该可以解决问题: 将DataTemplate 中的按钮替换为:

    <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>
    

    这里发生的是样式将 Visibility 属性设置为 Collapsed 并使用触发器来更改它。我使用了DataTrigger,所以你可以使用{Binding ...}。 使用{Binding RelativeSource={..}},您可以查找祖先,这里我们正在寻找ListBoxItem 类型的祖先。

    这样做是在 WPF 树中“向上”查找,以查看此按钮是否具有类型为 ListBoxItem 的 Parent 对象,如果找到,它将检查 IsSelected (Path=IsSelected) 属性是否为 True,并且将然后更新按钮的可见性属性。

    我希望这个解释是有道理的! :-)


    编辑2: 只是为了好玩,背后的代码方式:

    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;
    }
    

    我建议你使用 XAML 触发器“方式”,因为它更干净...

    【讨论】:

    • 这显示所有按钮,每个项目。按钮位于每个元素中。所以你的答案是错误的:/
    • 是的,我试过了。但你没有抓住重点。按钮在 ListBox 内重复。每个 ListBoxItem 都包含一个 StackPanel。请看我的例子。如果您想在列表中显示一个按钮,则您的示例有效。
    • 太棒了!这成功了。想详细说明你在那里真正做了什么?也许指出这些类型的绑定的一个很好的解释?
    • 我希望我的解释有道理!
    【解决方案2】:

    对列表中的选定项目使用转换器来确定可见性。

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

    这里是值转换器

    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.");
        }
    }
    

    【讨论】:

    • 您需要检查 SelectedItem 是否与按钮所在的 ListBoxItem 相同...
    • 是的,我误解了这个问题。
    【解决方案3】:

    如果您使用 MVVM 模式,您应该将您的按钮绑定到 ICommand,例如来自 MVVM Toolkit 的 DelegateCommand。这样,按钮将使用命令的 CanExecute() 状态自行决定是否应启用。

    【讨论】:

      猜你喜欢
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2012-12-22
      • 2010-11-11
      相关资源
      最近更新 更多