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

时间:2015-10-26 16:47:25

标签: c# wpf xaml

我有一个纯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>

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

我已经在应用过滤器后使用CollectionViewSourceFilterCollectionViewSource.View中的元素数量在代码中实现了此行为,但我更喜欢在没有代码的情况下实现这一点,仅在XAML中进行

修改 我需要一个通用的解决方案,可以在所有ComboBox中作为样式的一部分使用,而不是使用Person类型或IsAlive属性...因此解决方案应仅依赖于包含项的可见性属性

2 个答案:

答案 0 :(得分:0)

如果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 :(得分:0)

您对“组合框”项目进行“过滤”的方法不正确且非常高效[1]。您应该使用CollectionView / CollectionViewSource来过滤Persons集合,而不是在ItemContainerStyle中分配可见性。实现此目的后,您可以使用绑定的ComboBox.Visibility属性在CollectionView.IsEmpty属性中使用简单的绑定和转换器。

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