Question

I've found more than one reference to a VisibleChanged event on MSDN pages that state it is for the Windows Phone 8 platform. However, when I try to access it via Intellisense for either the top level user control I'm building (using the "this" keyword), or for the LayoutRoot grid, I don't see it. I did a full search via the Object Browser and I don't see anything there either. Where is it? I need to perform certain task only when the user control is visible, and I need them to stop when it is not.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.visiblechanged(v=vs.110).aspx

Was it helpful?

Solution

Your reference refers to Windows Form apps for Windows, not Windows Phone. The property you're asking about on Windows Phone is Visibility (not Visible) so you should be looking for VisibilityChanged--but that does not exist.

You could, however, create your own by subclassing the control for which you want the event then use your new control. For example:

public class MyControl : SomeOtherControl
{
    public MyControl()
    {
        DefaultStyleKey = typeof(MyControl);
    }

    public static readonly DependencyProperty VisibilityChangedProperty = DependencyProperty.Register(
        "VisibilityChanged",
        typeof(string),
        typeof(MyControl),
        new PropertyMetadata("VisibilityChanged event handler"));

    public event VisibilityChangedEventHandler VisibilityChanged;

    public delegate void VisibilityChangedEventHandler(object sender, EventArgs e);

    public new Visibility Visibility
    {
        get { return base.Visibility; }
        set
        {
            if (base.Visibility == value) return;
            base.Visibility = value;
            VisibilityChanged(this, new EventArgs());
        }
    }
}

Or, of course, if you have complete control of the control's source code, don't bother with the inheritance.

OTHER TIPS

If you want to have VisibilityChanged event for arbitrary controls, there is a slightly complicated workaround. First, create a wrapper class around that control that will have its own Visibility property and that is bound to the target's Visibility property. When you have that, you can listen for notifications.

First, the extension method:

public static FrameworkElementExtender Extender(this FrameworkElement element)
{
    return new FrameworkElementExtender(element);
}

Helper event args class:

public class VisibilityChangedEventArgs : EventArgs
{
    public Visibility Visibility { get; private set; }

    public VisibilityChangedEventArgs(Visibility visibility)
    {
        this.Visibility = visibility;
    }
}

And now for the actual wrapper:

public class FrameworkElementExtender : FrameworkElement
{
    public new static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register(
        "Visibility", typeof(Visibility), typeof(FrameworkElementExtender), new PropertyMetadata(default(Visibility), PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        ((FrameworkElementExtender)o).OnVisibilityChanged((System.Windows.Visibility)e.NewValue);
    }

    public new Visibility Visibility
    {
        get { return (Visibility)GetValue(VisibilityProperty); }
        set { SetValue(VisibilityProperty, value); }
    }

    private readonly FrameworkElement _element;

    public FrameworkElementExtender(FrameworkElement element)
    {
        _element = element;

        var binding = new Binding("Visibility")
        {
            Source = element,
        };

        SetBinding(VisibilityProperty, binding);
    }

    public event EventHandler<VisibilityChangedEventArgs> VisibilityChanged;

    protected virtual void OnVisibilityChanged(Visibility visible)
    {
        var handler = VisibilityChanged;
        if (handler != null)
            handler(this, new VisibilityChangedEventArgs(visible));
    }
}

As you can see, we listen for the changes in the target's dependency property and when we detect a change, we fire our own event. Using it is very simple:

control.Extender().VisibilityChanged += OnVisibilityChanged;
control.Visibility = Visibility.Collapsed;
control.Visibility = Visibility.Visible;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top