35

Is there a way in XAML to determine if the ListBox has data?

I wanna set its IsVisibile property to false if no data.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632

4 Answers4

51

The ListBox contains a HasItems property you can bind to. So you can just do this:

<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
...
<ListBox 
    Visibility="{Binding HasItems, 
      RelativeSource={RelativeSource Self}, 
      Converter=BooleanToVisibility}" />

Or as a Trigger so you don't need the converter:

<ListBox>
  <ListBox.Style>
    <Style TargetType="{x:Type ListBox}">
      <Setter Property="Visibility" Value="Visible" />
      <Style.Triggers>
        <DataTrigger 
            Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}"
            Value="False">
          <Setter Property="Visibility" Value="Hidden" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.Style>
</ListBox>

I haven't tested the bindings so there might be some typos but you should get the idea.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Bryan Anderson
  • 15,969
  • 8
  • 68
  • 83
  • 2
    +1 - this is a nice solution, and is cleaner than the trigger for the "zero items" situation. The trigger is useful if you want other behaviour or if you want to trigger something for a specific count of items. – Matt Hamilton Sep 08 '09 at 06:29
  • Matt, you're right, I will use the HasItem property but with a trigger as you suggested. – Shimmy Weitzhandler Sep 09 '09 at 01:42
  • and you know what' I think the HasItems is even a DependencyProperty! – Shimmy Weitzhandler Sep 09 '09 at 01:45
  • Agreed, this looks like the nicest answer. My background in Silverlight meant I hadn't seen RelativeSource before, and HasItems is clearly nicer than Items.Count. – Tristan Warner-Smith Sep 09 '09 at 09:02
  • 2
    Yes, HasItems is a DependencyProperty. You can bind to it and everything will update when the property changes. I don't think IEnumerable.Count will do that. – Bryan Anderson Sep 09 '09 at 16:36
  • Don't know why, but HasItems did not work for me: items.count was above zero, but HasItems was still false. – Zéiksz Mar 23 '13 at 22:23
  • @Zéiksz Were you binding to a collection that implements INotifyCollectionChanged? If not then the control is never informed that items were added/removed from the collection. – Bryan Anderson Mar 26 '13 at 23:29
14

Do it in a trigger and you won't need a ValueConverter:

<ListBox>
  <ListBox.Style>
    <Style TargetType="{x:Type ListBox}">
      <Style.Triggers>
        <DataTrigger 
          Binding="Items.Count, {Binding RelativeSource={RelativeSource Self}}"
          Value="0">
          <Setter Property="Visibility" Value="Hidden" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.Style>
</ListBox>

So that shows the ListBox by default, but if Items.Count is ever 0, the ListBox is hidden.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
  • 4
    Take a look at Bryan Anderson's post, he suggests to use the HasItems property of the listbox itself, which would be better than dig into the collection count. Matt's triggerring way is better and shorter than a conveter tho. – Shimmy Weitzhandler Sep 09 '09 at 01:44
2
<ListBox.Style>
    <Style TargetType="ListBox">
        <Setter Property="Visibility" Value="Visible"/>
        <Style.Triggers>
            <Trigger Property="HasItems" Value="False">
                <Setter Property="Visibility" Value="Hidden"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</ListBox.Style>
Sathya Ram
  • 581
  • 1
  • 7
  • 11
1

You can probably make this work using a ValueConverter and normal binding.

Set Visibility to be:

Visibility = "{Binding myListbox.Items.Count, Converter={StaticResource VisibilityConverter}}"

Then set up your converter to return Visibility.Collapsed etc based on the value of the count.

Tristan Warner-Smith
  • 9,631
  • 6
  • 46
  • 75