C# 根据Listbox ListboxItem选择的按钮可见性

C# 根据Listbox ListboxItem选择的按钮可见性,c#,wpf,listbox,show-hide,C#,Wpf,Listbox,Show Hide,我的情况如下 我想在未选择任何项目时隐藏删除按钮,并在选择某些项目时显示 如果用户选择了一个项目并单击了表示该用户不再使用列表框的其他位置,则还隐藏该按钮 我尝试了LostFocus事件,检查SelectedIndex等,但没有成功。你知道怎么做吗 private void ListBoxItem_LostFocus(object sender, RoutedEventArgs e) { if (button.IsFocused != true) // chec

我的情况如下

我想在未选择任何项目时隐藏删除按钮,并在选择某些项目时显示

如果用户选择了一个项目并单击了表示该用户不再使用列表框的其他位置,则还隐藏该按钮

我尝试了LostFocus事件,检查SelectedIndex等,但没有成功。你知道怎么做吗

    private void ListBoxItem_LostFocus(object sender, RoutedEventArgs e)
    {
        if (button.IsFocused != true) // checking if user has selected an item & clicking on button (valid action)
        {
            listbox.SelectedIndex = -1;
        }
    }

    private void listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listbox.SelectedIndex == -1)
        {
            button.Visibility = Visibility.Hidden;
        }
        else
        {
            button.Visibility = Visibility.Visible;
        }
    }

对于问题的前半部分,最好的方法是使用如下转换器: 1.添加转换器类:

 public class VisibilityConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (value == null ? Visibility.Hidden : Visibility.Visible);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
2.将其添加到窗口资源:

<Window.Resources>
        <wpfApplication:VisibilityConverter x:Key="VisibilityConverter"/>
</Window.Resources>
并添加以下处理程序,将列表的SelectedItem重置为null


只有当元素失去逻辑焦点时,LostFocus才会触发。使用LostKeyboardFocus事件。那你就更接近了。

约瑟夫的答案是正确的,但你不需要转换器

您可以通过一个简单的触发器获得相同的结果:

<ListBox>
    ...
    <ListBox.Style>
        <Style TargetType="{x:Type ListBox}">
            <Style.Triggers>
                <Trigger Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="YOUR_BUTTON'S_NAME" Property="Visibility" Value="Hidden"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.Style>
</ListBox>
编辑:在样式设置器中使用TargetName确实是不可能的

因此,我能找到的最接近的解决方案是创建一个DataTrigger:

<DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=MyList, Path=SelectedItem}"
                                 Value="{x:Null}">
                        <Setter Property="Visibility" Value="Hidden"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        <TextBlock Text="Button"/>
    </Button>
    <ListBox x:Name="MyList">
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
    </ListBox>
</DockPanel>

单独运行此代码,然后再试一次。在这里它对我有效

  <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <ListBox x:Name="lst">
            <ListBox.Triggers>
                <EventTrigger RoutedEvent="GotFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Visible}"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard> 
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="LostFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Collapsed}"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </ListBox.Triggers>
            <ListBoxItem>ListBoxItem1</ListBoxItem>
            <ListBoxItem>ListBoxItem2</ListBoxItem>
            <ListBoxItem>ListBoxItem3</ListBoxItem>
            <ListBoxItem>ListBoxItem4</ListBoxItem>
        </ListBox>
        <Button x:Name="DeleteButton"  Content="Delete" Height="30" Width="100">
            <Button.Style>
                <Style BasedOn="{StaticResource alredayDefinedStyleKey}"  TargetType="Button">
                    <Setter Property="Visibility" Value="Visible"></Setter>
                    <Style.Triggers>                           
                        <DataTrigger Binding="{Binding Path=SelectedItem, ElementName=lst}" Value="{x:Null}" >
                            <Setter Property="Visibility" Value="Collapsed"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>

    <ListBox Grid.Column="1">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
    </ListBox>
</Grid>

向我们展示你目前的工作:从可用性的角度来看,这是一个非常非常糟糕的想法。想象一个人,他第一次或很少看你的应用程序。他/她必须知道/记住,在项目未被选中且列表框已聚焦之前,可用操作的完整列表并不清楚。这并不明显,最好始终显示按钮,但在无法执行相关操作时禁用按钮。@Dennis:是的,我同意。但是在我的例子中,根据UI的设计,简单性是很重要的。用户不应该看到所有的东西都被启用/禁用,但它应该在必要时可用。1转换器在这里是多余的,将有足够一个简单的数据触发器。2以这种方式处理鼠标事件也会隐藏一个按钮,当用户尝试单击它时,尽管我不确定,现在无法检查。事实上,目前的问题并不是一条出路。因此,请随意发布所属的MVVM解决方案。不,当按钮或列表收到单击时,窗口将不会截获它,是的,我有点同意您的看法,使用转换器是一种过度工作,但我相信这是一种方法。@deafjeff什么MVVM解决方案@Joseph正在使用IPropertyChanged,但未更改按钮在代码中的可见性。错误-无法识别名称button1。@MangeshHotage如果按钮的x:name为button1,则该选项应可用。请加入此聊天并粘贴您的xaml:是否有任何未识别问题的解决方案?基本上,我正在努力做好这件事,基于SelectedIndex属性启用/禁用按钮,虽然我认为我可以从列表框样式中引用按钮,或者从按钮样式中引用列表框,但我也不知道该怎么做。不幸的是,您创建的聊天已被删除,并且此答案尚未更新以反映任何解决方案:@PeterDuniho我的回答确实不正确,因为你不能在一个样式中使用Setter的TargetName。一个解决方案是DataTrigger,我用一个工作解决方案编辑了我的答案,该解决方案要么是绑定集的ElementName,要么是RelativeSource。。只是一点点帮助。。当我点击按钮时,它会触发点击事件并消失。我可以防止它在单击时隐藏吗?否则它就像一个魔咒!将property Focusable=False设置为Button我想对多个按钮应用此设置。我的意思是,我有3个选项按钮&我需要为它们做同样的事情。此外,他们已经应用了一些其他样式。你能为这个案子提供解决方案吗?。请具体说明您的要求…………是否要显示列表框单个项目选择中所有3个可见按钮?
<ListBox>
    ...
    <ListBox.Style>
        <Style TargetType="{x:Type ListBox}">
            <Style.Triggers>
                <Trigger Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="YOUR_BUTTON'S_NAME" Property="Visibility" Value="Hidden"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.Style>
</ListBox>
<DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=MyList, Path=SelectedItem}"
                                 Value="{x:Null}">
                        <Setter Property="Visibility" Value="Hidden"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        <TextBlock Text="Button"/>
    </Button>
    <ListBox x:Name="MyList">
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
        <TextBlock Text="Something"/>
    </ListBox>
</DockPanel>
  <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <ListBox x:Name="lst">
            <ListBox.Triggers>
                <EventTrigger RoutedEvent="GotFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Visible}"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard> 
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="LostFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Collapsed}"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </ListBox.Triggers>
            <ListBoxItem>ListBoxItem1</ListBoxItem>
            <ListBoxItem>ListBoxItem2</ListBoxItem>
            <ListBoxItem>ListBoxItem3</ListBoxItem>
            <ListBoxItem>ListBoxItem4</ListBoxItem>
        </ListBox>
        <Button x:Name="DeleteButton"  Content="Delete" Height="30" Width="100">
            <Button.Style>
                <Style BasedOn="{StaticResource alredayDefinedStyleKey}"  TargetType="Button">
                    <Setter Property="Visibility" Value="Visible"></Setter>
                    <Style.Triggers>                           
                        <DataTrigger Binding="{Binding Path=SelectedItem, ElementName=lst}" Value="{x:Null}" >
                            <Setter Property="Visibility" Value="Collapsed"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>

    <ListBox Grid.Column="1">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
    </ListBox>
</Grid>