Search code examples
c#.netreflectionpropertyinfosetvalue

.NET PropertyInfo.SetValue seemingly ignoring my commands


As the topic suggests I have some problems with PropertyInfo.SetValue. To get to the point, here is my example - I have created my own class and the main thing about it is the presentation object:

using System;
using System.Reflection;

namespace TestingSetValue
{
public class Link
{
    private object presentationObject = null;
    private string captionInternal = string.Empty;

    public Link (string caption)
    {
        captionInternal = caption;
    }

    public string CaptionInternal
    {
        get { return captionInternal; }
        set { captionInternal = value; }
    }

    public bool Visible
    {
        get 
        {
            if (PresentationObject != null)
            {
                PropertyInfo pi = PresentationObject.GetType().GetProperty("Visible");

                if (pi != null)
                {
                    return Convert.ToBoolean(pi.GetValue(PresentationObject, null));
                }
            }

            return true;
        }

        set
        {
            if (PresentationObject != null)
            {
                PropertyInfo pi = PresentationObject.GetType().GetProperty("Visible");

                if (pi != null)
                {
                    pi.SetValue(PresentationObject, (bool)value, null);
                }
            }
        }
    }

    public object PresentationObject
    {
        get { return presentationObject; }
        set { presentationObject = value; }
    }

}

}

Then, I do this:

private void btnShowLink_Click(object sender, EventArgs e)
    {
        Link link = new Link("Here I am!");

        this.contextMenu.Items.Clear();
        this.contextMenu.Items.Add(link.CaptionInternal);

        link.PresentationObject = this.contextMenu.Items[0];
        link.Visible = true;

        lblCurrentVisibility.Text = link.Visible.ToString();
    }

Now, I can imagine this doesn't look too logical/ economical, but it shows the essence of my real problem. Namely, why doesn't the visibility of presentation object (and the value of link.Visible) change, after I call:

link.Visible = true;

I simply do not know what else to do to make this work... Any help is deeply appreciated.

To make things even more interesting, the property Enabled behaves as expected of it...

PropertyInfo pi = PresentationObject.GetType().GetProperty("Enabled");

Could it be related to the fact that Visible is actually a property of ToolStripDropDownItem base base object, whereas Enabled is 'direct' property of ToolStripDropDownItem ?


Solution

  • It would have been easier to figure this out if you said upfront what class this is but now we know it is ToolStripDropDownItem which we can infer means WinForms.

    What you are seeing is an oddity with the ToolStripItem's Visible property. It's setter & getter are not tied directly together. MSDN says

    "The Available property is different from the Visible property in that Available indicates whether the ToolStripItem is shown, while Visible indicates whether the ToolStripItem and its parent are shown. Setting either Available or Visible to true or false sets the other property to true or false."

    In other words, you want to use the Available property instead of the Visible property