|
How can I get and for that matter set the paper name, or as my Canon printer properties calls it 'Media Type', I'm writing a program where I have to keep setting my printer paper type to 'High resolution' so I was hoping to save the exact name to a config file and then set the printer paper to the same name if it exists.
I do find the printer stuff really hard going so any help would be great.
|
|
|
|
|
We are building a huge application for use by both business and developers. We chose the propertyGrid UI as the best interface for these two roles.
In our mapping sessions, we defined that business changes would be allowed only on fields that changed look-and-feel, but not anything that changes the behaviour. I have two NT groups established so security defines the role each user is in (business vs. developer).
We have the initial property object defined with everything set for
ReadOnly(false) Does anyone know of a way to dynamically alter the attribute for the various fields so that I can set fields to ReadOnly if userType=Business ????
Thanks
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
We have an application I architected that does something similar. The answer lies in implement ICustomTypeDescriptor . In your implementation of GetProperties , you can return a PropertyDescriptorCollection with derived PropertyDescriptor classes, where the implementation for the PropertyDescriptor.ReadOnly uses the Thread.CurrentPrincipal (set to a WindowsPrincipal for WindowsIdentity.GetCurrent ) to see if a user is in one role or another (or some other similar means, though role-based security is easy and effective in .NET applications). You could further extend this by making your own attribute that contains a group or groups required to edit the attributed property (using the params keyword in the attribute constructor would be helpful here).
There's a lot of other great things you can do by implementing ICustomTypeDescriptor . Read and docs for it and I'm sure you'll agree! Note that for methods you don't want to have to "implement", you can use the appropriate TypeDescriptor method that takes a bool that dictates whether ICustomTypeDescriptor should be used:
public class MyClass : ICustomTypeDescriptor
{
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm lost. I searched everywhere and could find no articles on ICustomTypeDescriptor. I tried deploying my own TypeDescriptor but I'm getting lost in all of the methods I have to create and not really understanding when the attribute methods and property methods apply to my TypeConverter and when they apply to the property I am a part of.
My attempt, in general, is this:
public class Secure : ICustomTypeDescriptor
{
private bool isSecure;
public Secure(bool state)
{
isSecure = state;
}
.. now I'm lost trying to deploy everything
}
I also cannot find PropertyDescriptor.ReadOnly or when I should use it or add it or whatever. I found an abstract conversation on one site and this is similar to what they showed. My attempt:
namespace myCompany.Attributes
{
internal class Secured : ICustomTypeDescriptor
{
private bool secured;
private bool readonlyState;
public Secured(bool state)
{
secured = state;
}
System.ComponentModel.PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(System.Attribute[]
attributes)
{
PropertyInfo[] propInfos =
this.classType.GetProperties(BindingFlags.Public | BindingFlags.Static);
ArrayList props = new ArrayList(propInfos.Length);
foreach(PropertyInfo propInfo in propInfos)
{
props.Add( new ReflectPropertyDescriptor(propInfo) );
}
if (CheckReadOnlyState())
props.Add(new ReflectProperty(???));
return new PropertyDescriptorCollection(
(PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)) );
}
System.ComponentModel.PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
ArrayList props = new ArrayList();
if (CheckReadOnlyState())
props.Add(new ReflectPropertyDescriptor(PropertyDescriptor.ReadOnly));
return new PropertyDescriptorCollection((PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)));
}
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(this.secured, true);
}
public bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
{
}
}
public class bool CheckReadOnlyState()
{
readonlyState = true;
SecurityManager sec = new SecurityManager();
if (sec.CheckUserGroup("D-U-TCAEDIT") && !this.secured)
{
readonlyState = false;
}
if (sec.CheckUserGroup("D-U-TCA"))
{
readonlyState = false;
}
return readonlyState;
}
public class PropertyDescriptor ReflectPropertyDescriptor : PropertyDescriptor
{
private PropertyInfo propInfo;
public ReflectPropertyDescriptor(PropertyInfo propInfo) :
base(propInfo.Name, null)
{
this.propInfo = propInfo;
}
}
I'm just not understanding what this is doing and how I define the ReadOnly(true/false) attribute.
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
You don't define the attribute, you extend the PropertyDescriptor class and override the ReadOnly property. What this property does to determine if true or false should be returned is up to your implementation. If you're setting the Thread.CurrentPrincipal to the current Windows principal (rather, the current WindowsIdentity with a WindowsPrincipal), you can use <code>IPrincipal.IsInRole (actually, you could do this without setting Thread.CurrentPrincipal , but this opens you up for role-based code access security as well). You could also attribute your properties subject to this condition with an attribute that dictates which roles are required.
The point is, in your ICustomTypeDescriptor.GetProperties implementation, you return a collection of your derived PropertyDescriptos that override the ReadOnly property.
For more information about ICustomTypeDescriptor , merely type it in your help index in VS.NET (if you installed the documentation, which is installed by default).
As far as all the methods, as I mentioned earlier you can provide the default implementation by using the appropriate TypeDescriptor method. I put that in my previous post. Each method declared by ICustomTypeDescriptor has a corresponding method defined by TypeDescriptor that takes a bool as (typically) the last parameter. Set this to true so that the implementation does NOT query your Type for the ICustomTypeDescriptor implementation (which would cause an infinite loop).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Okay....I'm a very visual person so it takes some time to absorb some things. Our Security Manager handles the group determination by WindowsIdentity.
I think I've got it now:
namespace myCompany.Attributes
{
internal class SecuredProperty : PropertyDescriptor
{
private bool readonlyState;
public bool IsReadOnly
{
get{return readonlyState;}
}
public SecuredProperty()
{
SecurityManager sec = new SecurityManager();
if (sec.CheckUserGroup("D-U-TCAEDIT") && !secured)
{
readonlyState = false;
}
if (sec.CheckUserGroup("D-U-TCA"))
{
readonlyState = false;
}
}
}
internal class SecureDescriptor : ICustomTypeDescriptor
{
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{ return TypeDescriptor.GetAttributes(this.secured, true); }
string ICustomTypeDescriptor.GetClassName()
{ return TypeDescriptor.GetClassName(this, true); }
string ICustomTypeDescriptor.GetComponentName()
{ return TypeDescriptor.GetComponentName(this, true); }
TypeConverter ICustomTypeDescriptor.GetConverter()
{ return TypeDescriptor.GetConverter(this, true); }
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{ return TypeDescriptor.GetDefaultEvent(this, true); }
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{ return TypeDescriptor.GetDefaultProperty(this, true); }
object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{ return TypeDescriptor.GetEditor(this, editorBaseType, true); }
EventDescriptor ICustomTypeDescriptor.GetEvents(System.Attribute[] attribs)
{ return TypeDescriptor.GetEvents(this, attribs, true); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{ return new PropertyDescriptorCollection(new SecuredProperty(secured)); }
}
}
I also understand that I can create a public class Secured:Attribute and have it indicate if the particular property should be secured to just developers. There are just two things I am not completely clear on which is not covered in the help files.
1) In my PropertyDescriptor class or within my CustomTypeDescriptor how do I determine that the Secured Attribute is set to (true) ?
2) When I define all of this in my properties, I'm not clear how I define my CustomTypeDescriptor.
[Description("..."), Secured(true), TypeEditor(typeof(myEditor)),
Category("Viewing"), ...]
Do I specify a CustomTypeDescriptor, or a TypeDescriptor(typeof(SecureDescriptor)) ?
Thanks very much for your assistance!
Michael
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
You don't have to attribute you class with anything to make use of the ICustomTypeDescriptor . Any object that uses the TypeDescriptor to get information - like the PropertyGrid - will automatically benefit from the ICustomTypeDescriptor implementation.
As far as the attribute goes, I would do something like this:
public class RequiredGroupsAttribute : Attribute
{
private string[] groups;
public RequiredGroupsAttribute(params string[] groups)
{
this.groups = groups;
}
public string[] Groups
{
get { return this.groups; }
}
public bool IsInGroup(string group)
{
if (this.groups == null) return false;
foreach (string s in this.groups)
if (string.Compare(s, group, true) == 0) return true;
return false;
}
} In your derived PropertyDescriptor , you can get the attributes of the property like so:
public override bool IsReadOnly
{
get
{
RequiredGroupsAttribute attr = (RequiredGroupsAttribute)
this.Attributes[typeof(RequiredGroupsAttribute)];
if (attr == null) return true;
return !attr.IsInGroup("Developers");
}
} This is just a very simple example, though. You could most likely improve upon it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath,
Thanks much for your help. I have the ICustomTypeDescriptor mostly done and implemented in my property objects. I have the Secured() Attribute defined and recognized by the system. I am lost still with implementing the PropertyDescriptor. It is not a simple process of just overriding IsReadOnly. There are about 10 methods and properties that need to be implemented. Some of these I can just pass to the base class. Some are not definable. And I cannot see how I can implement these PropertyDescriptors completely.
For example: I assume that if I call TypeDescriptor.GetProperties I have the initial collection of properties with all of their attributes. But some of the properties (such as Category, Description, etc.) are not accessible as anything but get in the base class and I cannot set the properties from the original.
I have read what little is in the help files and all they do is provide a 1-line description. I cannot find a tutorial anywhere that implements even a simple example of this.
So how exactly do I define my own property descriptor, get it implemented for all my properties, and get a properly deployed PropertyDescriptorCollection returned when the GetProperties method is called since I cannot tell TypeDescriptor to use my PropertyDescriptor object and I cannot set my base properties internally nor can I override them.
I appreciate your patience and help on this!
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
PropertyDescriptor has a protected constructor that you should override that takes and initializes the PropertyDescriptor from a MemberDescriptor , which you can get with TypeDescriptor.GetProperties(this, true) . In your override for IsReadOnly , you can use metadata to determine if the user can set them or not. I do this very thing in our application based on dynamic properties pulled form a database. As I mentioned before, it you utility role-based security, this gets very easy. That attribute I mentioned before would have the groups (or roles) that can set the property. Your IsReadOnly override gets the list, calls IPrincipal.IsInRole and if it returns true for any of those roles, you return false . If not, return true (read-only).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am almost there....just can't get the last pieces defined.
My CustomTypeDescriptor.GetProperties calls
TypeDescriptor.GetProperties(this,attributes,true);
I then create a new PropertyTypeCollection and make each PropertyDescriptor my custom PropertyDescriptor. I pass the PropertyDescriptor as the MemberDescriptor object.
protected PropertyDescriptorCollection GetFilteredReadonlyProperties(Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this, attributes, true);
PropertyDescriptorCollection newProperties = new PropertyDescriptorCollection(new PropertyDescriptor[0]);
foreach (PropertyDescriptor property in properties)
{
DynamicPropertyDescriptor newProp = new DynamicPropertyDescriptor(property);
newProperties.Add(newProp);
}
return newProperties;
}
I cannot figure out what I code, though within these abstract methods:
PropertyDescriptor.PropertyType()
PropertyDescirptor.GetValue()
PropertyDescriptor.SetValue()
PropertyDescriptor.ComponentType()
Since these are abstract....I cannot do a base.method().
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
PropertyType returns the Type of the property. Just return obj.GetType() . ComponentType returns the Type of the component that the property belongs to. GetValue and SetValue set the property for the object to which the property belongs. You can use reflection to achieve this.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I finally got it WORKING!!! Thank you Heath.
While the help files provided no help looking up PropertyDescriptor, I found more help looking up the PropertyDescriptor.{method name} where they had some more useful info under the Note to Inheritor: sections. That combined with Reflection finished it off.
I think in my freetime ( ????) I will put together a sample application and publish it as a visual aid for those developers who are like me and need more visual assistance!
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
When I tell people to look in the documentation for some class, I do mean everything about that class. Remember, it's Research and development. The latter without the former is what separates the developers from the code-monkeys.
I'm glad you have it working. The important thing is to understand what a MemberDescriptor does so you can utilize it to its full potential. For instance, I have a derivation that uses rows from a couple tables in a database for a completely object-oriented and extensible way of managing preferences. Those properties work great with a PropertyGrid but also have a parent collection that can get and set different property containers using a singleton pattern. All this is done with classes and interfaces in the System.ComponentModel namespace. It's a very cool namespace to fully understand when dealing with component development because there are so many things supported by designers that ship with the .NET Framework and with common IDEs like VS.NET and SharpDevelop.
Just thought I'd mention this more as an exmaple of what else you can do with PropertyDescriptor s and related classes.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
can you tell me how to pass a integer command line parameter in C# I am struggling with this
Please let me know at the earliest
Praveen
|
|
|
|
|
Only strings can be passed, hence an string[] array being passed to your entry point method (typically Main ) or Environment.GetCommadLineArgs() returning a string[] . Therefore, you should be looking for a way to convert the string. There are many ways to do this, such as Int32.Parse and Convert.ToInt32(String) .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
how can i execute a file
e.g. if i have a file c:\text.exe or d:\test.htm
So if i have a textbox and the user enter the filelocation enter a filename.
if it is an application, i want execute that application, if it is a document, i want execute the defeault program for reading that file
in VB6 there was an execute API, i thougt Shellexecute
But how can i do this in c#
|
|
|
|
|
Check for Process.Start() and ProcessStartInfo classin MSDN.
Mazy
"Improvisation is the touchstone of wit." - Molière
|
|
|
|
|
Thanks
But if the filetype is not registered an error occur.
Can i view the 'Open With...' dialog
|
|
|
|
|
Use ProcessStartInfo and set UseShellExecute and ErrorDialog both to true :
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = myTextBox.Text;
info.UseShellExecute = true;
info.ErrorDialog = true;
Process.Start(info); Be sure to read the class documentation for additional members to see what other features exist.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
One way to do this is to use System.Diagnostics.Process...
using System.Diagnostics;
.
.
.
//
// opens an instance of notepad with the file c:\mytest.xsd
//
private void OpenTheFileInNotepad(string fileName)
{
Process.Start("notepad.exe",fileName);
}
see MSDN at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDiagnosticsProcessClassTopic.asp
|
|
|
|
|
I have used String array and integer for one console application.
But size of the executable is 16kb. can u help me in this view.
|
|
|
|
|
Can you explain more the relation of size of executable file with the use of String Array and integer in your applicattion?
Mazy
"Improvisation is the touchstone of wit." - Molière
|
|
|
|
|
I am using a string array which is having 13 constants and i am comparing with other 13 constants.
When i built that executable file its size is 16kb but i feel 16kb is very costly.
Please explain me
Regards,
|
|
|
|
|
GetOn&GetGoing wrote:
When i built that executable file its size is 16kb but i feel 16kb is very costly.
Is it? Then perhaps you should consider using something other than the .NET Framework. I have done some experiments and the smallest application I could build was 16kb.
Also consider that when your application is running it will be loading .NET Framework DLLs. The 16kb size of this executable is a drop in the ocean compared with the size of the Framework.
--Colin Mackay--
EuroCPian Spring 2004 Get Together[^]
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
|
|
|
|
|
Yah, they are really small in size. The only time I got smaller than this, somtimes in VC6 which I used some win32 applicationns with some specific compile attribute which lead to very small size like 3 to 5 Kb.
Mazy
"Improvisation is the touchstone of wit." - Molière
|
|
|
|