Search code examples
c#wpfxamlmvvmdockpanel

Top Dock in a DockPanel is taking all the space


My code looks something like this:

<DockPanel>
  <Expander DockPanel.Dock="Top" Name="Expander1">
     <local:ListView1 DataContext="{Binding Source1}"/>
  </Expander>
  <Expander DockPanel.Dock="Top" Name="Expander2">
     <local:ListView1 DataContext="{Binding Source2}"/>
  </Expander>
  <Expander DockPanel.Dock="Top" Name="Expander3">
     <local:ListView1 DataContext="{Binding Source3}"/>
  </Expander>
</DockPanel>

ListView1 is just a user control that contains a ListView

I have the behavior set: when one Expander is open, all the other 2 Expanders will close.

enter image description here

enter image description here

The problem is that when Expander1 is open and its content is more than the window height, it will have a scroll bar to scroll down for its content while Expander2 and Expander3 are not displayed. I think Expander1 uses all the space on the UI and Expander2 & Expander3 get pushed out side of the UI. When Expander2 is open, Expander3 is pushed out of the UI and not displayed. What can I do so that when I open an Expander, the one(s) below it won't get pushed out of the UI?


Solution

  • You said you're only allowing one open at a time.

    Given that then the size logic is simpler and you could use just a converter with a fixed number.

    My PoC:

    <DockPanel>
        <Expander DockPanel.Dock="Top" MaxHeight="{Binding ActualHeight, 
            RelativeSource={RelativeSource AncestorType=ContentPresenter}, 
            Converter={local:AddConverter ValueToAdd=-46}}">
            <ListBox ItemsSource="{Binding Items}"/>
        </Expander>
        <Expander DockPanel.Dock="Top" MaxHeight="{Binding ActualHeight, 
            RelativeSource={RelativeSource AncestorType=ContentPresenter}, 
            Converter={local:AddConverter ValueToAdd=-46}}">
            <ListBox ItemsSource="{Binding Items}"/>
        </Expander>
        <Expander DockPanel.Dock="Top" MaxHeight="{Binding ActualHeight, 
            RelativeSource={RelativeSource AncestorType=ContentPresenter}, 
            Converter={local:AddConverter ValueToAdd=-46}}">
            <ListBox ItemsSource="{Binding Items}"/>
        </Expander>
    </DockPanel>
    

    And the converter

    public class AddConverter : MarkupExtension, IValueConverter
    {
        public double ValueToAdd { get; set; }
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double bound = (Double)value;
            return bound + ValueToAdd;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
    

    enter image description here

    As I mentioned in the comments.

    You could make this more sophisticated with a multibinding and multiconverter. That could allow for height when 2 are open.