Pages

Thursday, May 26, 2016

DataGrid extensions for the Compact Framework

DataGrid extensions for the Compact Framework

InfoDabble > Tech Notes > DataGrid extensions for the Compact Framework
By Eric Hartwell -- February 25, 2008
Customized DataGrid control sample showing the ComboBox column in action.
Customized DataGrid control sample showing the ComboBox column in action.
Microsoft says, "The DataGrid class in the .NET Compact Framework provides the core functionality of the Windows Forms DataGrid class in the full .NET Framework." That's a bit like saying a rock provides the core functionality of a nuclear submarine.
The Compact Framework provides a subset of the functionality of the full .NET Framework. That's what makes it compact. Ok, but ...
<rant>did it never occur to anyone at Microsoft that the user interface is even more important in mobile applications than in Windows or web applications?</rant>
To be honest, it's not as bad as it looks. Way back in April, 2006, the Microsoft .NET Compact Framework Team published atech note with samples showing how to customize the DataGrid control, adding such field types as editable, formatted text, checkbox, pulldown lists, a date picker, and an up/down control. Unfortunately there's very little documentation with the sample.
 I've added a C# version of the sample application, updated to target Windows Mobile 5.0. Download it here.

C# code

The SetupTableStyles function must be called in the form's Load event handler rather than the constructor since the data and screen need to be initialized before it will work.
It would be nice to add designer support so the custom grid can be initialized directly from the screen builder. As always, adding designer support to compact framework controls is needlessly painful, but I'll try ...
private void SetupTableStyles()
{
   Color alternatingColor = SystemColors.ControlDark;
   DataTable vehicle = dataSource.Tables[1];
 
   // ID Column 
   DataGridCustomTextBoxColumn dataGridCustomColumn0 = new DataGridCustomTextBoxColumn();
   dataGridCustomColumn0.Owner = this.dataGrid1;
   dataGridCustomColumn0.Format = "0##";
   dataGridCustomColumn0.FormatInfo = null;
   dataGridCustomColumn0.HeaderText = vehicle.Columns[0].ColumnName;
   dataGridCustomColumn0.MappingName = vehicle.Columns[0].ColumnName;
   dataGridCustomColumn0.Width = dataGrid1.Width * 10 / 100;    // 10% of grid size
   dataGridCustomColumn0.AlternatingBackColor = alternatingColor;
   dataGridCustomColumn0.ReadOnly = true;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn0);
 
   // Make column
   DataGridCustomTextBoxColumn dataGridCustomColumn1 = new DataGridCustomTextBoxColumn();
   dataGridCustomColumn1.Owner = this.dataGrid1;
   dataGridCustomColumn1.HeaderText = vehicle.Columns[1].ColumnName;
   dataGridCustomColumn1.MappingName = vehicle.Columns[1].ColumnName;
   dataGridCustomColumn1.NullText = "-Probably Ford-";
   dataGridCustomColumn1.Width = dataGrid1.Width * 40 / 100;     // 40% of grid size
   dataGridCustomColumn1.Alignment = HorizontalAlignment.Right;
   dataGridCustomColumn1.AlternatingBackColor = alternatingColor;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn1);
 
   // Mileage column
   DataGridCustomUpDownColumn dataGridCustomColumn2 = new DataGridCustomUpDownColumn();
   dataGridCustomColumn2.Owner = this.dataGrid1;
   dataGridCustomColumn2.HeaderText = vehicle.Columns[2].ColumnName;
   dataGridCustomColumn2.MappingName = vehicle.Columns[2].ColumnName;
   dataGridCustomColumn2.NullText = "-Unknown-";
   dataGridCustomColumn2.Width = dataGrid1.Width * 20 / 100;     // 20% of grid size
   dataGridCustomColumn2.Alignment = HorizontalAlignment.Left;
   dataGridCustomColumn2.AlternatingBackColor = alternatingColor;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn2);
 
   // Availability column 
   DataGridCustomCheckBoxColumn dataGridCustomColumn3 = new DataGridCustomCheckBoxColumn();
   dataGridCustomColumn3.Owner = this.dataGrid1;
   dataGridCustomColumn3.HeaderText = vehicle.Columns[3].ColumnName;
   dataGridCustomColumn3.MappingName = vehicle.Columns[3].ColumnName;
   dataGridCustomColumn3.NullText = "-Unknown-";
   dataGridCustomColumn3.Width = dataGrid1.Width * 10 / 100;     // 10% of grid size
   dataGridCustomColumn3.Alignment = HorizontalAlignment.Left;
   dataGridCustomColumn3.AlternatingBackColor = alternatingColor;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn3);
 
   // Fuel Level column
   DataGridCustomComboBoxColumn dataGridCustomColumn4 = new DataGridCustomComboBoxColumn();
   dataGridCustomColumn4.Owner = this.dataGrid1;
   dataGridCustomColumn4.HeaderText = vehicle.Columns[4].ColumnName;
   dataGridCustomColumn4.MappingName = vehicle.Columns[4].ColumnName;
   dataGridCustomColumn4.NullText = "-Unknown-";
   dataGridCustomColumn4.Width = dataGrid1.Width * 30 / 100;     // 30% of grid size
   dataGridCustomColumn4.Alignment = HorizontalAlignment.Left;
   dataGridCustomColumn4.AlternatingBackColor = alternatingColor;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn4);
 
   // Last Used column
   DataGridCustomDateTimePickerColumn dataGridCustomColumn5 = new DataGridCustomDateTimePickerColumn();
   dataGridCustomColumn5.Owner = this.dataGrid1;
   dataGridCustomColumn5.HeaderText = vehicle.Columns[5].ColumnName;
   dataGridCustomColumn5.MappingName = vehicle.Columns[5].ColumnName;
   dataGridCustomColumn5.NullText = "-Unknown-";
   dataGridCustomColumn5.Width = dataGrid1.Width * 30 / 100;     // 30% of grid size
   dataGridCustomColumn5.Alignment = HorizontalAlignment.Left;
   dataGridCustomColumn5.AlternatingBackColor = alternatingColor;
   dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn5);
 
   // Grid, mapping
   dataGridTableStyle1.MappingName = vehicle.TableName;                       // Setup table mapping name
   dataGrid1.DataSource = vehicle;         
 
   // Setup grid's data source
   ComboBox cb = (ComboBox)dataGridCustomColumn4.HostedControl;
   DataTable fuel = dataSource.Tables[0];                                                    // Set up data source
   cb.DataSource = fuel;           
 
   // For combo box column
   cb.DisplayMember = fuel.Columns[0].ColumnName;
   cb.ValueMember = fuel.Columns[0].ColumnName;
 
   dataGrid1.CurrentRowIndex = 50;                                                            // Move to the middle of the table
}

Code notes

Note the funky cast when setting up the combo box's data source. This is because the HostedControl is exposed as the base Control class.
ComboBox cb = (ComboBox)dataGridCustomColumn4.HostedControl;

How did they do that?

The Compact Framework 2.0 Service Pack 1 introduced the following extensions to provide better data formatting and custom cell drawing:
  • DataGridColumnStyle
    • PropertyDescriptor descriptor allows access to this column data in the data source so it could be processed as needed.
    • Paint() method is called as cell is drawn. Overriding it allows representing data from data source in any way imaginable. Colors, fonts, formatting, alignment, pictures and more - anything is possible as long as it can be painted. CurrencyManager and row number along with PropertyDescriptor allows fetching data from data source to convert and format the way you want.
  • DataGridTextBoxColumn
    • Format string to be used to format data in the column. To be used the same way as on desktop or in simple data binding.
    • IFormatProvider FormatInfo Format provider to be used to format data in the column. To be used the same way as on desktop or in simple data binding.

Links

Friday, May 20, 2016

Android Phone Screen on PC debug

It's likely that the device is no longer authorized on ADB for whatever reason.
ADB path C:\Users\LoggedinUser\AppData\Local\Android\sdk\platform-tools
1. Check if authorized:
<ANDROID_SDK_HOME>\platform-tools>adb devices
List of devices attached
4df798d76f98cf6d        unauthorized
2. Revoke USB Debugging on phone
If the device is shown as unauthorized, go to the developer options on the phone and click "Revoke USB debugging authorization" (tested with JellyBean & Samsung GalaxyIII).
3. Restart ADB Server:
Then restarted adb server
adb kill-server
adb start-server
4. Reconnect the device
The device will ask if you are agree to connect the computer id. You need to confirm it.
5. Now Check the device
It is now authorized!
adb devices
<ANDROID_SDK_HOME>\platform-tools>adb devices
List of devices attached
4df798d76f98cf6d        device