tags:

views:

706

answers:

3

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

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

A: 

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.

TreeUK
`ItemCollection.Count` is not a dependency property and the binding will not get updated when the number of items in the collection changes.
Martin Liversage
<ListBox Visibility="{Binding Items.Count, RelativeSource={RelativeSource Self}, Converter={StaticResource EmptyListVisibilityConverter}}"/>
Shimmy
Martin, you seem to be right, but the above code works for me.probably the collection changed event refreshed the visibilty property as well.
Shimmy
I would expect a pure 'xamly' item but I assume there is no other way without using a converter.I think wpf should have builtin conditional converters as boolean terms, boolean switch; or and > < = etc. operators etc.
Shimmy
@Martin, take a look on Bryan Anderson's response.
Shimmy
+8  A: 

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

<ListBox>
    <ListBox.Style>
        <Style TargetType="{x:Type ListBox}">
            <Setter Property="Visibility" Value="Visible" />

            <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.

Matt Hamilton
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
+5  A: 

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.

Bryan Anderson
+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
Matt, you're right, I will use the HasItem property but with a trigger as you suggested.
Shimmy
and you know what' I think the HasItems is even a DependencyProperty!
Shimmy
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.
TreeUK
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