How can I implement an owner drawn listview
Carlos Perez explains how to do this in an article and a sample on codeproject.com. In this sample, he does an owner-drawn listview so he can implement custom sorting with a column header that contains a up/down icon to indicate the sorted column and order.
From within a PropertyGrid, is there any way to display property names that differ from the actual class property names
You can do this but it’s not as simple as using an attribute. If you want to modify the property names for your component, you have to interact with the reflection mechanism that the grid is using by implementing ICustomTypeDescriptor. The grid operates on objects called PropertyDescriptors with are the Framework’s generic wrapper for a property, where reflection is a specific implementation. So what ICustomTypeDescriptor allows you to do is to have *your object* asked for it’s properties rather than than the default system, which is reflection. You then write your own derived version of PropertyDescriptor (an abstract class in System.ComponentModel) and return your property descriptors instead of the ones that come back from the TypeDescriptor… so some of the impl would look something like this. public class MyFriendlyNamePropertyDescriptor : PropertyDescriptor { private PropertyDescriptor baseProp; private string friendlyName; public MyFriendlyNamePropertyDescriptor(PropertyDescriptor baseProp, Attribute[] filter) : base(baseProp) { this.baseProp = baseProp; } public override string Name { get{return this.baseProp.Name;} } public override string DisplayName { get { return GetFriendlyname(baseProp.Name); //replace with code to return a friendly name } } public override bool IsReadOnly { get {return baseProp.IsReadOnly;} } public override bool CanResetValue(object component) { return this.baseProp.CanResetValue(component); } public override Type ComponentType { get{return baseProp.ComponentType;} } public override object GetValue(object component) { return this.baseProp.GetValue(component); } public override Type PropertyType { get{return this.baseProp.PropertyType;} } public override void ResetValue(object component) { baseProp.ResetValue(component); } public override void SetValue(object component, object Value) { this.baseProp.SetValue(component, Value); } public override bool ShouldSerializeValue(object component) { return this.baseProp.ShouldSerializeValue(component); } } public class MyClass : ICustomTypeDescriptor { PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] filter) { PropertyDescriptorCollection baseProps = TypeDescriptor.GetProperties(GetType(), filter); // notice we use the type here so we don’t recurse PropertyDescriptor[] newProps = new PropertyDescriptor[baseProps.Count]; for (int i = 0; i < baseProps.Count; i++) { newProps[i] = new MyFriendlyNamePropertyDescriptor(baseProps[i], filter); string oldname = ((PropertyDescriptor)baseProps[i]).DisplayName ; string newname = ((MyFriendlyNamePropertyDescriptor)newProps[i]).DisplayName; } // probably wanna cache this… return new PropertyDescriptorCollection(newProps); } AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, 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); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return TypeDescriptor.GetProperties(this, true); } object ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } object ICustomTypeDescriptor.GetPropertyOwner(System.ComponentModel.PropertyDescriptor pd) { return this; } // the code for MyClass…. including the properties to show in the propertygrid } (originally from [email protected] on microsoft.public.dotnet.framework.windowsforms. This code suggested by Rachid El Masoudi in an email to [email protected])
How do I make the RichTextBox support drag and drop
1) Set the AllowDrop property to true 2) Add handlers for both the DragEnter and DragDrop event this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter); this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter); …. private void richTextBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) { if (((DragEventArgs)e).Data.GetDataPresent(DataFormats.Text)) ((DragEventArgs)e).Effect = DragDropEffects.Copy; else ((DragEventArgs)e).Effect = DragDropEffects.None; } private void richTextBox1_DragDrop(object sender, DragEventArgs e) { // Loads the file into the control. richTextBox1.LoadFile((String)e.Data.GetData(‘Text’), System.Windows.Forms.RichTextBoxStreamType.RichText); } Here are VB snippets. AddHandler Me.richTextBox1.DragEnter, New System.Windows.Forms.DragEventHandler(AddressOf Me.richTextBox1_DragEnter) AddHandler Me.richTextBox1.DragDrop, New System.Windows.Forms.DragEventHandler(AddressOf Me.richTextBox1_DragEnter) ….. Private Sub richTextBox1_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs) If CType(e, DragEventArgs).Data.GetDataPresent(DataFormats.Text) Then CType(e, DragEventArgs).Effect = DragDropEffects.Copy Else CType(e, DragEventArgs).Effect = DragDropEffects.None End If End Sub ’richTextBox1_DragEnter Private Sub richTextBox1_DragDrop(sender As Object, e As DragEventArgs) ’ Loads the file into the control. richTextBox1.LoadFile(CType(e.Data.GetData(‘Text’), [String]), System.Windows.Forms.RichTextBoxStreamType.RichText) End Sub ’richTextBox1_DragDrop
How do I find the top-left visible cell in a datagrid
In a Windows Forms DataGrid, there is no property exposed that gives you this information. But here is little trick that will allow you to get the top-left visible cell. 1) Add a private member Point pointInCell00 to the form containing the datagrid. 2) After the datagrid has been initialized, but before your user has been able to scroll it (say at the end of the Form_Load event), use code such as this to initialize pointInCell00 to be a point in cell 0,0. pointInCell00 = new Point(dataGrid1.GetCellBounds(0,0).X + 4, dataGrid1.GetCellBounds(0,0).Y + 4); 3) Then add this method to return DataGridCell that is the top-left cell. public DataGridCell TopLeftVisibleCell() { DataGrid.HitTestInfo hti = dataGrid1.HitTest(this.pointInCell00); return new DataGridCell(hti.Row, hti.Column); } //sample usage… private void button1_Click(object sender, System.EventArgs e) { DataGridCell dgc = TopLeftVisibleCell(); MessageBox.Show(dgc.RowNumber.ToString() + ‘ ‘ + dgc.ColumnNumber.ToString()); }
How do you provide ‘dynamic’ default values
Provide ShouldSerialize#PropertyName# and Reset#PropertyName# along with your property. Example: private bool ShouldSerializeFont() { return this.bFontSet; } /// /// Resets the property to its default value. /// private void ResetFont() { this.localFont = null; }