当ListBox
中的一个被选中时,我有一个ListBoxItems
我想要更改“查看”按钮的可见性并显示它。意味着默认状态为隐藏。
这是可能的吗?如果可以的话,我是用XAML中的触发器还是后面的代码来解决这个问题?
XAML Piece
<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>
答案 0 :(得分:7)
[老无用的代码]
编辑:
好吧,我没有读好这个问题,但这应该可以解决问题:
将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树中查找“up”以查看此按钮是否具有ListBoxItem
类型的Parent对象,如果发现它将检查IsSelected(Path=IsSelected
)属性,如果它是True,然后会更新按钮的Visibility属性。
我希望这个解释有意义! : - )
EDIT2: 只是为了好玩,代码背后的方式:
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 Trigger“方式”,因为它更干净......
答案 1 :(得分:0)
在列表中的选定项目上使用转换器以确定可见性。
<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.");
}
}
答案 2 :(得分:0)
如果您正在使用MVVM模式,则应将按钮绑定到ICommand,例如MVVM Toolkit中的DelegateCommand。这样按钮将使用命令的CanExecute()状态自行决定是否应该启用它。