Search code examples
wpftextblockdatatrigger

WPF Hide TextBlock if one collection count equal another


Hullo,

I'm setting up my WPF pane to display some text based on the values of several view model collections that are bound to a ListView.

The text is displayed as in a stack panel which displays the number of views in a collection, followed by another TextBlock which displays if any are hidden.

This is worked out by the following bindings:

Browser.Count = this is the total number of views

BrowserItemCollectionView.Count = this is the number of views hidden

Basically, I want the text to hide if Browser.Count == BrowserItemCollectionView.Count

This is the XAML code

                    <StackPanel Orientation="Horizontal">

                    <TextBlock x:Name="TotalCount"
                               Foreground="#FF6F6F6F">
                        <Run Text="{Binding Path=Browser.Count, Mode=OneWay}" />
                        <Run Text=" Views" />
                    </TextBlock>
                    
                    <TextBlock x:Name="SearchCount"
                               Foreground="#FF6F6F6F">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">

                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=BrowserItemCollectionView.Count, Mode=OneWay}"
                                                 Value="---SOME CLEVER BINDING HERE---">
                                        <Setter Property="UIElement.Visibility"
                                                Value="Hidden" />
                                    </DataTrigger>
                                </Style.Triggers>

                            </Style>
                        </TextBlock.Style>
                        <Run Text=", ("></Run>
                        <Run Text="{Binding Path=BrowserItemCollectionView.Count, Mode=OneWay}"></Run>
                        <Run Text=" visible.)"></Run>
                    </TextBlock>

                </StackPanel>

So I thought this would easy enough to change the DataTrigger above with:

                <DataTrigger Binding="{Binding Path=BrowserItemCollectionView.Count, Mode=OneWay}"
                             Value="{Binding Path=Browser.Count, Mode=OneWay}">
                       <Setter Property="UIElement.Visibility"
                               Value="Hidden" />
                </DataTrigger>

But this doesn't work as the error states that a Value cannot be set to a binding...

What would be the simplest way of doing this?

Thanks.


Solution

  • You can use DataTrigger with MultiBinding.

    <DataTrigger Value="True">
        <DataTrigger.Binding>
            <MultiBinding Converter="{StaticResource MyCustomConverter}">
                <Binding Path="BrowserItemCollectionView.Count" />
                <Binding Path="Browser.Count" />
            </MultiBinding>
        </DataTrigger.Binding>
        <Setter Property="UIElement.Visibility" Value="Hidden" />
    </DataTrigger>
    

    Bind to two properties and use MultiValueConverter to check if values of those properties are equal.

    public class MyCustomConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length != 2)
            {
                return false;
            }
            var value1 = values[0];
            var value2 = values[1];
    
            return value1.Equals(value2);
    
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    The second option is to create a bool property on your view model and make a logic in your view model which will set that property to true/false. Bind to that property in DataTrigger.

    private bool collectionsEqual;
    public bool CollectionsEqual
    {
        get { return collectionsEqual; }
        set
        {
            collectionEqual = value;
            OnPropertyChanged()
        }
    }
    ...
    <DataTrigger Binding="{Binding Path=CollectionsEqual}" Value="True">
        <Setter Property="UIElement.Visibility" Value="Hidden" />
    </DataTrigger>