繁体   English   中英

隐藏XAML中没有可见项目的WPF ComboBox

[英]Hide WPF ComboBox without visible items in XAML

在折叠所有ComboBox项时,是否存在一种纯粹的XAML方式来隐藏ComboBox?

例如,我有一个组合框:

<ComboBox ItemsSource="{Binding Persons}">
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="Visibility" Value="{Binding IsAlive, Converter={StaticResource BoolToVis}}" />
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

预期的行为:如果所有人都死了,则组合框不可见,但是如果至少一个人还活着,则组合框可见(并且仅显示活着的人)

我已经在代码中使用CollectionViewSourceFilter和应用了filter之后的CollectionViewSource.View的元素计数在代码中实现了此行为,但是我更喜欢在没有代码行为的情况下仅在XAML中实现该行为。

编辑:我需要在样式表的所有ComboBox中可用的通用解决方案,而不是分配给Person类型或IsAlive属性...因此解决方案应仅取决于所包含项目的可见性属性

如果items属性为null,为空或其中的所有项目都不可见(Visibility.Collapsed),则可以使用此附加属性隐藏组合框。

创建一个新的类ComboBoxExt(或任何您想调用的类),然后添加一个附加属性。 (提示:您可以在Visual Studio中输入“ propa”,然后选择两次制表符,它将为您提供附加属性的模板)

public class ComboBoxExt
  {
    public static bool GetHideOnEmpty(DependencyObject obj)
    {
      return (bool)obj.GetValue(HideOnEmptyProperty);
    }

    public static void SetHideOnEmpty(DependencyObject obj, bool value)
    {
      obj.SetValue(HideOnEmptyProperty, value);
    }

    public static readonly DependencyProperty HideOnEmptyProperty =
        DependencyProperty.RegisterAttached("HideOnEmpty", typeof(bool), typeof(ComboBoxExt), new UIPropertyMetadata(false, HideOnEmptyChanged));

    private static void HideOnEmptyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      var cbox = d as ComboBox;

      if (cbox == null)
        return;

      HideComboBox(cbox, (bool)e.NewValue);
    }
    //This is where we check if all the items are not visible
    static void HideComboBox(ComboBox cbox, bool val)
    {
      //First, we have to know if the HideOnEmpty property is set to true. 
      if (val)
      {
        //Check if the combobox is either null or empty
        if (cbox.Items == null || cbox.Items.Count < 1)
          cbox.Visibility = Visibility.Collapsed; //Hide the combobox
        else
        {
          bool hide = true;
          //Check if all the items are not visible.  
          foreach (ComboBoxItem i in cbox.Items)
          {
            if (i.Visibility == Visibility.Visible)
            {
              hide = false;
              break;
            }
          }

          //If one or more items above is visible we won't hide the combobox.
          if (!hide)
            cbox.Visibility = Visibility.Visible;
          else
            cbox.Visibility = Visibility.Collapsed;
        }
      }
    }
  }

现在,您可以在所需的每个组合框中重复使用附加的属性。 您只需要将HideOnEmpty设置为true。

<ComboBox local:ComboBoxExt.HideOnEmpty="True"/>

使用此解决方案,您将无需编写任何代码,并且可以在所需的每个组合框上重用附加的属性HideOnEmpty。

您“过滤”组合框项目的方法不正确,并且效果很差[1]。 您应该使用CollectionView / CollectionViewSource来过滤Persons集合,并且不要在ItemContainerStyle分配可见性。 完成此操作后,可以使用绑定的CollectionView.IsEmpty属性在ComboBox.Visibility属性中使用简单的绑定和转换器。

[1]关于性能:当前,将在评估可见性绑定之前为每个Person对象创建一个容器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM