4

Is there a way to control which items leave the visible area of a stackpanel when resizing?
Thanks

UPDATE 1
I have a fixed number of buttons inside a stackpanel. When resizing the visible area of the stackpanel, each button automatically hides or shows depending on the available space. What I'd like to achieve, through some event, control which of button hides or shows when stackpanel resizing occurs.

The reason is, I'd like to create a minimized version of the button instead of hiding the button.

Serch00
  • 51
  • 4
  • Can you provide a bit more detail on what you are looking to do? – Xcalibur37 Mar 19 '13 at 12:48
  • perhaps this could help http://stackoverflow.com/questions/1517743/in-wpf-how-can-i-determine-whether-a-control-is-visible-to-the-user – Klaus78 Mar 19 '13 at 12:53
  • So, why not just use the SizeChanged event of the StackPanel and observe it's dimensions? – Xcalibur37 Mar 19 '13 at 13:02
  • @Xcalibur37 The stackpanel is inside a Grid cell which also has a splitter control. When I move the splitter control up and down it’s when the Grid cell resizes which is forcing the stackpanel to resize. For some reason the "SizeChanged" event of the stackpanel doesn't fire when I move the splitter. – Serch00 Mar 19 '13 at 13:22
  • 1
    ok, what is the container type around the button content (within the split area)? – Xcalibur37 Mar 19 '13 at 13:31
  • @Xcalibur37 If I understand you correctly, your're asking if the buttons are contained within another container? The answer is no, the stackpanel control directly contains the buttons. – Serch00 Mar 19 '13 at 16:01

2 Answers2

1

In the past I have done something like this by altering the ContentTemplate of an object based on the object's size.

Typically I add an event to both the Loaded and SizeChanged events of the parent object, and from there figure out if the control is visible or not. If not, I change the template to a smaller version of the template.

In reference to your comment here about the SizeChanged event not firing, that is probably because you have your objects in a StackPanel, which will grow/shrink to fit the size of it's children, not to match the size of it's parent (the Grid cell).

You can probably also do this using a DataTrigger and Converter on the actual UI object, so it automatically checks to see if the Template should changed when the control's ActualWidth or ActualHeight changes.

I have a helper class I use to determine the exact visibility of a UI control within it's parent object, to find out if it's fully or partially visible, or hidden entirely. The code can be found in this answer, although I'll also copy it here:

public enum ControlVisibility
{
    Hidden,
    Partial,
    Full,
    FullHeightPartialWidth,
    FullWidthPartialHeight
}


/// <summary>
/// Checks to see if an object is rendered visible within a parent container
/// </summary>
/// <param name="child">UI element of child object</param>
/// <param name="parent">UI Element of parent object</param>
/// <returns>ControlVisibility Enum</returns>
public static ControlVisibility IsObjectVisibleInContainer(
    FrameworkElement child, UIElement parent)
{
    GeneralTransform childTransform = child.TransformToAncestor(parent);
    Rect childSize = childTransform.TransformBounds(
        new Rect(new Point(0, 0), new Point(child.Width, child.Height)));

    Rect result = Rect.Intersect(
        new Rect(new Point(0, 0), parent.RenderSize), childSize);

    if (result == Rect.Empty)
    {
        return ControlVisibility.Hidden;
    }
    if (result.Height == childSize.Height && result.Width == childSize.Width)
    {
        return ControlVisibility.Full;
    }
    if (result.Height == childSize.Height)
    {
        return ControlVisibility.FullHeightPartialWidth;
    }
    if (result.Width == childSize.Width)
    {
        return ControlVisibility.FullWidthPartialHeight;
    }
    return ControlVisibility.Partial;
}

You can get a control's visibility like this:

ControlVisibility ctrlVisibility = 
    WPFHelpers.IsObjectVisibleInContainer(button, parent);

if (ctrlVisibility == ControlVisibility.Full 
    || isVisible == ControlVisibility.FullWidthPartialHeight)
{
    // Set big template
}
else
{
    // Set little template
}
Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
1

The reason why the "SizeChanged" event wasn't firing was that I had set it's height to a fixed value. After setting it to "auto" the event fired when resizing it's parent container.

Serch00
  • 51
  • 4