Cast error/Select attribut

Jan 23, 2012 at 9:35 PM

I want to use the propertygrid but I set my propertygrid with a class I created "Node".

I first would like to know if it is possible to choose the attributs that are displayed? I currently have all attributs on screen and I only want to be able to modify 5 of them :$

I also have an issu, I can create my propertygrid but after creating it, I want to use my node and a message indicating a cast error appear... How can I solved that? :$

Thx in advance :)

Coordinator
Jan 23, 2012 at 9:40 PM

To hide class properties from showing up in the PropertyGrid, place the [BrowsableAttribute(true|flase)] as appropriate.

Casting errors is a good indication that you may need a custom TypeConverter.

Jan 23, 2012 at 9:46 PM

Thx, but how could I use these typeConverter? :$

I also have an other issu, I am trying to create a list :

List<Attribute> list = new List<Attribute>();
 foreach (Attribute att in mnd.Items)
{
   list.Add(att);
}

propertyGrid.SelectedObject = list;

But I only have Capacity : 4 and Count : 4 in my property grid, shouldn't it display my attribut? :$

Coordinator
Jan 23, 2012 at 10:08 PM

Can you share your Attribute class?

Jan 23, 2012 at 10:12 PM

Here is my attribut class :

 

public class Attribute : INotifyPropertyChanged
    {
        public Attribute(String name, String value, bool iskey, NodeFigure fig, String color)
        {
            this.Name = name;
            this.IsKey = iskey;
            this.Figure = fig;
            this.Color = color;
            this.Value = value;
        }
        public String Value
        {
            get { return _Value; }
            set
            {
                if (_Value != value)
                {
                    String old = _Value;
                    _Value = value;
                    RaisePropertyChanged("Value", old, value);
                }
            }
        }
        private String _Value;

    public String Name {
      get { return _Name; }
      set {
        if (_Name != value) {
          String old = _Name;
          _Name = value;
          RaisePropertyChanged("Name", old, value);
        }
      }
    }
    private String _Name;

    public bool IsKey {
      get { return _IsKey; }
      set {
        if (_IsKey != value) {
          bool old = _IsKey;
          _IsKey = value;
          RaisePropertyChanged("IsKey", old, value);
        }
      }
    }
    private bool _IsKey;

    public NodeFigure Figure {
      get { return _Figure; }
      set {
        if (_Figure != value) {
          NodeFigure old = _Figure;
          _Figure = value;
          RaisePropertyChanged("Figure", old, value);
        }
      }
    }
    private NodeFigure _Figure = NodeFigure.DiskStorage;

    public String Color {
      get { return _Color; }
      set {
        if (_Color != value) {
          String old = _Color;
          _Color = value;
          RaisePropertyChanged("Color", old, value);
        }
      }
    }
    private String _Color;

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(String pname, Object oldval, Object newval)
    {
      if (this.PropertyChanged != null)
      {
        this.PropertyChanged(this, new ModelChangedEventArgs(pname, this, oldval, newval));
      }
    }
    }

Coordinator
Jan 23, 2012 at 10:14 PM

Got it, ok you need to have a default constructor for you class.

Also, the .NET ComponentModel and hence the PropertyGrid does not use INPC so you don't need to use that for use with the PropertyGrid.

It does however use the system Attributes in the System.ComponentModel namespace.

Jan 23, 2012 at 10:29 PM

public Attribute(String name, String value, bool iskey, NodeFigure fig, String color)
        {
            this.Name = name;
            this.IsKey = iskey;
            this.Figure = fig;
            this.Color = color;
            this.Value = value;
        }

 

This is not my default constructor? :O

Coordinator
Jan 23, 2012 at 10:30 PM

I created the NodeFigure enum and tested, see linked to picture...

https://skydrive.live.com/redir.aspx?cid=c0c9fd4e384405e0&resid=C0C9FD4E384405E0!1127&parid=C0C9FD4E384405E0!111&authkey=!AOAgSx7iiFJywW0

 

Coordinator
Jan 23, 2012 at 10:31 PM

Sorry a default constructor with no parameters.

-- Add this constructor to your class
public Attribute() { }

Coordinator
Jan 23, 2012 at 10:40 PM

Also, I had to rename your ModelPropertyChangedEventArgs to PropertyChangedEventArgs

Jan 23, 2012 at 10:45 PM

I have this but it still doesn't work...

<slg:PropertyGrid Name="propertyGrid" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>

 

List<Attribute> list = new List<Attribute>();
foreach (Attribute att in mnd.Items)
      {
           list.Add(att);
      }
tableurExcel.ItemsSource = list;
propertyGrid.SelectedObject = list;

 

public class Attribute : INotifyPropertyChanged
    {

        public Attribute() { }

        public Attribute(String name, String value, bool iskey, NodeFigure fig, String color)
        {
            this.Name = name;
            this.IsKey = iskey;
            this.Figure = fig;
            this.Color = color;
            this.Value = value;
        }

    // Property setters need to raise the PropertyChanged event,
    // only when the value has changed, and passing both the previous and the new values

        public String Value
        {
            get { return _Value; }
            set
            {
                if (_Value != value)
                {
                    String old = _Value;
                    _Value = value;
                    RaisePropertyChanged("Value", old, value);
                }
            }
        }
        private String _Value;


        public String Name {
          get { return _Name; }
          set {
            if (_Name != value) {
              String old = _Name;
              _Name = value;
              RaisePropertyChanged("Name", old, value);
            }
          }
        }
        private String _Name;

        public bool IsKey {
          get { return _IsKey; }
          set {
            if (_IsKey != value) {
              bool old = _IsKey;
              _IsKey = value;
              RaisePropertyChanged("IsKey", old, value);
            }
          }
        }
        private bool _IsKey;

        public NodeFigure Figure {
          get { return _Figure; }
          set {
            if (_Figure != value) {
              NodeFigure old = _Figure;
              _Figure = value;
              RaisePropertyChanged("Figure", old, value);
            }
          }
        }
        private NodeFigure _Figure = NodeFigure.DiskStorage;

        public String Color {
          get { return _Color; }
          set {
            if (_Color != value) {
              String old = _Color;
              _Color = value;
              RaisePropertyChanged("Color", old, value);
            }
          }
        }
        private String _Color;

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(String pname, Object oldval, Object newval)
        {
          if (this.PropertyChanged != null)
          {
            this.PropertyChanged(this, new ModelChangedEventArgs(pname, this, oldval, newval));
          }
        }
    }

I had the default constructor but I have the same result :S

Coordinator
Jan 23, 2012 at 10:58 PM

If you want to manage a list of Type Attribute, that list needs to be contained in another class or you have to write your own custom editor.

Remember the only public properties of a List<T> are Capacity and Count

Try this...

public class MyAttributes
{
	public MyAttributes()
	{
		this.Atts = new List<SLPropertyGrid.Attribute>();
		for (int i = 0; i < 10; i++)
			this.Atts.Add(new SLPropertyGrid.Attribute());
	}

	public List<SLPropertyGrid.Attribute> Atts
	{
		get;
		set;
	}
}
Then 
this.propertyGrid.SelectedObject = new MyAttributes();
Jan 23, 2012 at 11:29 PM

Thx, I didn't well understand the SLPropertyGrid.Attribute but I am going to find :)

I have a last question... :$

If my class herits from an other :

public class MyData : GraphLinksModelNodeData<String>

I would like to use [BrowsableAttribute(false)] on an attribut call "Location" which is part of GraphLinksModelNodeData, how could I do that in MyData? :$

Thx again for your help :)

Coordinator
Jan 23, 2012 at 11:35 PM

SLPropertyGrid.Attribute is your class you gave me, i just added to my test project.

You can't put the [Browsable(false)] on Location because you don't have the source.

If it's not sealed, you can create a new class, and specify the GraphsLinksModelNodeData as the base class

Then make a new property named Location. Be sure and define with the new keyword

public MyCustomModel : GraphLinksModelNodeData
{
    [Browsable(false)]
    public new Location
    {
        get{ return base.Location; }
        set { base.Location = value; }
    }
}

Coordinator
Jan 23, 2012 at 11:40 PM

But since you're getting the GraphsLink object instance from some where beyond you're control, my advice above won't solve your problem 100%. You will need to cast the GraphLinksModelNodeData instance to your MyCustomModel. I added a helper method to my example class just for convenience.

public MyCustomModel : GraphLinksModelNodeData
{
    public static MyCustomModel FromNode(GraphLinksModelNodeData node)
    {
        return node as MyCustomModel;
    }


    [Browsable(false)]
    public new Location
    {
        get{ return base.Location; }
        set { base.Location = value; }
    }
}
Jan 24, 2012 at 12:00 AM

Thanks a lot!!! :)

Coordinator
Jan 24, 2012 at 12:01 AM

No problem, glad I could help.