Ray61
Ray61

Reputation: 1

How to add a linklabel in a PropertyGrid in Windows Forms

we have an information tool that displays information from active directory on a gui. I want to extend that tool to the part that i can click on a text to open a file. I am struggeling with the function to do the text clickable.

The tool was made in Windows Forms and VB.net.

My code to create a category in a propertygrid is:

<Description(""),
    Category("UserHistory Log"), [ReadOnly](True), Browsable(True), DisplayName("Computerlog")>
    Public ReadOnly Property ComputerLog() As String
        Get
            Return "press here"
        End Get
    End Property

Its like this:

enter image description here

How can i make it clickable? Do you have any clue?

I read about linklabels. But i am not sure how to implement a linklabel into a propertygrid without drag&drop because the form itself is clear.

Upvotes: 0

Views: 288

Answers (2)

Reza Aghaei
Reza Aghaei

Reputation: 125292

Another totally different approach, adding DesignerVerbs which shows above description panel, at bottom of property grid:

enter image description here

private void Form1_Load(object sender, EventArgs e)
{
    this.propertyGrid1.SelectedObject = new Test();
    //For .NET projects the field is _hotcommands
    //For .NET Framework projects the field is hotcommands
    var hotcommands = propertyGrid1.GetType()
        .GetField("hotcommands",
            System.Reflection.BindingFlags.NonPublic |
            System.Reflection.BindingFlags.Instance)
        .GetValue(propertyGrid1);

    var clickVerb = new DesignerVerb("Click me!",
        (obj, args) => { MessageBox.Show("Clicked!"); });
    hotcommands.GetType().GetMethod("SetVerbs")
        .Invoke(hotcommands, new object[] {
            propertyGrid1.SelectedObject,
            new []{ clickVerb }
        });
}

And you don't need the dummy property:

public class Test
{
    public string AnotherProperty { get; set; } = "Something else";
}

Upvotes: 0

Reza Aghaei
Reza Aghaei

Reputation: 125292

There's no built in support for showing a link in the property editor; in addition to the text, you can show an icon, a custom glyph, a dropdown button or a dots button.

You can also handle the click event of grid entries.

Handling the click might be good enough for you. But if you would like to show a link label in the property grid, the following code shows you a nice hack (read dirty hack 😄), so that when you click on the property it shows the link label:

enter image description here

private void Form1_Load(object sender, EventArgs e)
{
    this.propertyGrid1.SelectedObject = new Test();
    //For .NET projects the field is _gridView
    //For .NET Framework projects the field is gridView
    var gridView = propertyGrid1.GetType()
        .GetField("gridView",
            System.Reflection.BindingFlags.NonPublic |
            System.Reflection.BindingFlags.Instance)
        .GetValue(propertyGrid1);
    var edit = gridView.GetType()
        .GetProperty("Edit",
            System.Reflection.BindingFlags.NonPublic |
            System.Reflection.BindingFlags.Instance)
        .GetValue(gridView) as TextBox;

    var linkLabel = new LinkLabel()
    {
        Text = "Click me!",
        LinkArea = new LinkArea(0, 9),
        Dock = DockStyle.Fill,
        AutoSize = false,
        Visible = propertyGrid1.SelectedGridItem?.PropertyDescriptor?.Name == "MyProperty"
    };
    linkLabel.LinkClicked += (obj, args) =>
    {
        MessageBox.Show("Link clicked");
    };
    edit.Controls.Add(linkLabel);
    propertyGrid1.SelectedGridItemChanged += (obj, args) =>
    {
        var name = args.NewSelection?.PropertyDescriptor?.Name;
        linkLabel.Visible = name == "MyProperty";
    };
    edit.Enter += (obj, args) =>
    {
        var name = propertyGrid1.SelectedGridItem?.PropertyDescriptor?.Name;
        linkLabel.Visible = name == "MyProperty";
    };
}

And this is the test class:

public class Test
{
    [ReadOnly(true)]
    public string MyProperty { get; set; } = "Click me!";
    public string AnotherProperty { get; set; } = "Something else";
}

To use the code, make sure you bind the event handler to the event.

Upvotes: 0

Related Questions