2

I have a Control that I want to automatically disappear if another control has no visibile children. I'm not sure how to implement that though. I feel as though I need to create a binding that returns bindings for each child element's visible property and then aggregates them into a MultiValueConverter. I think it is working but it seems as though when I add items to my collection, the collection binding isn't being re-evaluated. Has anyone done this before?

Below is my code:

    <Grid.Resources>
        <local:BindingExpander x:Key="BindingExpander"/>
        <local:TestConverter x:Key="TestConverter" />
    </Grid.Resources>

    <Button Content="Button" HorizontalAlignment="Left" Margin="237,166,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click">
        <Button.Visibility>
            <MultiBinding Converter="{StaticResource TestConverter}">
                <Binding ElementName="lstItems" Path="Items" Converter="{StaticResource BindingExpander}" ConverterParameter="Visibility"/>
            </MultiBinding>
        </Button.Visibility>
    </Button>

    <ListBox x:Name="lstItems" HorizontalAlignment="Left" Height="100" Margin="601,130,0,0" VerticalAlignment="Top" Width="100" DisplayMemberPath="Content"/>

and:

public class TestConverter : IMultiValueConverter {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        var ret = Visibility.Collapsed;

        foreach (var item in values) {
            if(item is IEnumerable IE) {
                foreach (var Child in IE) {

                }
            }
        }

        return ret;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}

public class BindingExpander : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        var ret = new List<Binding>();
        if(value is IEnumerable IE) {
            foreach (var item in IE) {
                ret.Add(new Binding(parameter.ToString()) {
                    Source = item,
                    Mode = BindingMode.OneWay
                });
            }
        }

        return ret;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}

````

Tony Valenti
  • 11
  • 1
  • 9

1 Answers1

1

I have a Control that I want to automatically disappear if another control has no visibile children..

Simply create a Boolean property which reports the status of what the other control is binding to such as:

public bool HasItems { get { return _SomeArray?.Any(); }}

This property can be as elaborate as needed, but a basic one above for the example is shown.

Then bind the visibility flag of the control in question to the HasItems.

Note that the HasItems does not have the plumbing for INotifyPropertyChanged. In the code(s) where items are added to the _SomeArray simply put in a call to PropertyChanged("HasItems")


On my blog I provide a basic example of that (Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding) which looks like this where someone would bind to IsMemebershipAtMax such as what you are doing:

   public bool IsMembershipAtMax 
    {
        get { return MemberCount > 3; }
    }
    public int MemberCount 
    { 
        get { return _MemberCount; }
        set
        {
            _MemberCount = value; 
            OnPropertyChanged();
            OnPropertyChanged("IsMembershipAtMax");
        } 
    }

    public List<string> Members 
    { 
        get { return _Members; }
        set { _Members = value; OnPropertyChanged(); } 
    }
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122