问题描述
I have a ListBox
when one of the ListBoxItems
are selected I want to change the visibility of the button "View" and display it.意味着默认状态是隐藏.
I have a ListBox
when one of the ListBoxItems
are selected I want to change the visibility of the button "View" and display it. Meaning that the default state is Hidden.
这可能吗?如果可以,我是否可以使用 XAML 中的触发器或代码隐藏来解决此问题?
Is this possible and if so, do I solve this with a trigger in XAML or in code behind?
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>
推荐答案
【老的没用的代码】
好吧,我没有很好地阅读这个问题,但这应该可以解决问题:将 DataTemplate
中的按钮替换为:
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>
这里发生的事情是样式将 Visibility 属性设置为 Collapsed 并使用触发器来更改它.我使用了 DataTrigger
,因此您可以使用 {Binding ...}
.使用 {Binding RelativeSource={..}}
您可以查找 Ancestor,这里我们正在查找类型为 ListBoxItem
的 Ancestor.
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
.
这样做是在 WPF 树中向上"查找,以查看此按钮是否具有类型为 ListBoxItem
的 Parent 对象,如果找到,它将检查 IsSelected (Path=IsSelected
) 属性,如果它是 True,然后将更新按钮的 Visibility 属性.
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! :-)
只是为了好玩,背后的代码方式:
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;
}
我建议你使用 XAML 触发器方式",因为它更干净...
I suggest you use the XAML Trigger "way" because it's much cleaner...
这篇关于仅在选择 ListViewItem 时显示内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!