How do I programmatically determine the selected rows in a datagrid

The method DataGrid.IsSelected can tell you if a particular row is selected. So, you could use IsSelected in a loop through all your rows to finds if multiple rows have been selected. Depending upon the size of your datagrid, this may be a viable solution. If not, you could track the selections yourself by monitoring the key actions and the mouse actions. This would be more work. Thanks to John Hughes to the suggestion to use the dataview. [C#] public ArrayList GetSelectedRows(DataGrid dg) { ArrayList al = new ArrayList(); CurrencyManager cm = (CurrencyManager)this.BindingContext[dg.DataSource, dg.DataMember]; DataView dv = (DataView)cm.List; for(int i = 0; i < dv.Count; ++i) { if(dg.IsSelected(i)) al.Add(i); } return al; } private void button1_Click(object sender, System.EventArgs e) { string s = ‘Selected rows:’; foreach(object o in GetSelectedRows(dataGrid1)) { s+=”+o.ToString(); } MessageBox.Show(s); } [VB.NET] Public Function GetSelectedRows(ByVal dg As DataGrid) As System.Collections.ArrayList Dim al As New ArrayList() Dim cm As CurrencyManager = Me.BindingContext(dg.DataSource, dg.DataMember) Dim dv As DataView = CType(cm.List, DataView) Dim i As Integer For i = 0 to dv.Count – 1 If dg.IsSelected(i) Then al.Add(i) End If End Next Return al End Function ’GetSelectedRows Private Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim s As String = ‘Selected rows:’ Dim o As Object For Each o In GetSelectedRows(dataGrid1) s += ‘ ‘ + o.ToString() Next o MessageBox.Show(s) End Sub ’button1_Click

I get a ‘This would cause two bindings in the collection to bind to the same property’ error message. What might cause this

As the message suggests, the code is calling Control.DataBindings.Add twice with what amounts to the same parameters. One way this might happen is if you call the same code more than once in your program to reload your datasource for some reason, and in this code, you have lines such as: Me.TextBox1.DataBindings.Add(‘Text’, myDataTable, ‘Col1Name’) Me.TextBox2.DataBindings.Add(‘Text’, myDataTable, ‘Col2Name’) Me.TextBox3.DataBindings.Add(‘Text’, myDataTable, ‘Col3Name’) On the second call, this would attempt to add a duplicate binding to the DataBindings collection. One solution is to Clear the DataBindings collection before you add your new binding. Me.TextBox1.DataBindings.Clear(); Me.TextBox1.DataBindings.Add(‘Text’, myDataTable, ‘Col1Name’) Me.TextBox2.DataBindings.Clear(); Me.TextBox2.DataBindings.Add(‘Text’, myDataTable, ‘Col2Name’) Me.TextBox3.DataBindings.Clear(); Me.TextBox3.DataBindings.Add(‘Text’, myDataTable, ‘Col3Name’)

Why am I not being able to set a Color.Transparent color as a background to my control?

Sometimes the framework will throw an exception if you try to set the bg color to be transparent. This is because the Control doesn’t support transparent colors. To work around this you should call this method from within the Control: [C#] this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); [VB.Net] Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True) Depending on the Control, you might also have to perform some custom drawing, then.

Is there a way to force some contrast between two colors (like background color and foreground color)?

Here is a routine that will let you do this. The code below uses the routine from our previous faq how to translate a HSB color to RGB color. [C#] /// <summary> /// Adjusts the specified Fore Color’s brightness based on the specified back color and preferred contrast. /// </summary> /// <param name=”foreColor”>The fore Color to adjust. /// <param name=”backColor”>The back Color for reference. /// <param name=”prefContrastLevel”>Preferred contrast level. /// <remarks> /// This method checks if the current contrast in brightness between the 2 colors is /// less than the specified contrast level. If so, it brigtens or darkens the fore color appropriately. /// </remarks> public static void AdjustForeColorBrightnessForBackColor(ref Color foreColor, Color backColor, float prefContrastLevel) { float fBrightness = foreColor.GetBrightness(); float bBrightness = backColor.GetBrightness(); float curContrast = fBrightness – bBrightness; float delta = prefContrastLevel – (float)Math.Abs(curContrast); if((float)Math.Abs(curContrast) < prefContrastLevel) { if(bBrightness < 0.5f) { fBrightness = bBrightness + prefContrastLevel; if(fBrightness > 1.0f) fBrightness = 1.0f; } else { fBrightness = bBrightness – prefContrastLevel; if(fBrightness < 0.0f) fBrightness = 0.0f; } float newr, newg, newb; ConvertHSBToRGB(foreColor.GetHue(), foreColor.GetSaturation(), fBrightness, out newr, out newg, out newb); foreColor = Color.FromArgb(foreColor.A, (int)Math.Floor(newr * 255f), (int)Math.Floor(newg * 255f), (int)Math.Floor(newb * 255f)); } } [VB.Net] ’/ <summary> ’/ Adjusts the specified Fore Color’s brightness based on the specified back color and preferred contrast. ’/ </summary> ’/ <param name=”foreColor”>The fore Color to adjust. ’/ <param name=”backColor”>The back Color for reference. ’/ <param name=”prefContrastLevel”>Preferred contrast level. ’/ <remarks> ’/ This method checks if the current contrast in brightness between the 2 colors is ’/ less than the specified contrast level. If so, it brigtens or darkens the fore color appropriately. ’/ </remarks> Public Shared Sub AdjustForeColorBrightnessForBackColor(ByRef foreColor As Color, backColor As Color, prefContrastLevel As Single) Dim fBrightness As Single = foreColor.GetBrightness() Dim bBrightness As Single = backColor.GetBrightness() Dim curContrast As Single = fBrightness – bBrightness Dim delta As Single = prefContrastLevel – System.Convert.ToSingle(Math.Abs(curContrast)) If System.Convert.ToSingle(Math.Abs(curContrast)) < prefContrastLevel Then If bBrightness < 0.5F Then fBrightness = bBrightness + prefContrastLevel If fBrightness > 1F Then fBrightness = 1F End If Else fBrightness = bBrightness – prefContrastLevel If fBrightness < 0F Then fBrightness = 0F End If End If Dim newr, newg, newb As Single ConvertHSBToRGB(foreColor.GetHue(), foreColor.GetSaturation(), fBrightness, newr, newg, newb) foreColor = Color.FromArgb(foreColor.A, Fix(Math.Floor((newr * 255F))), Fix(Math.Floor((newg * 255F))), Fix(Math.Floor((newb * 255F)))) End If End Sub ’AdjustForeColorBrightnessForBackColor

How do you translate a HSB color to RGB?

Here is a routine that does this. Note that the conversion is not precise but very close. (Please do post any better algorithm in our forums). [C#] // This does not seem to yield accurate results, but very close. public static void ConvertHSBToRGB(float h, float s, float v, out float r, out float g, out float b) { if (s == 0f) { // if s = 0 then h is undefined r = v; g = v; b = v; } else { float hue = (float)h; if (h == 360.0f) { hue = 0.0f; } hue /= 60.0f; int i = (int)Math.Floor((double)hue); float f = hue – i; float p = v * (1.0f – s); float q = v * (1.0f – (s * f)); float t = v * (1.0f – (s * (1 – f))); switch(i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; default: r = 0.0f; g = 0.0f; b = 0.0f; break; /*Trace.Assert(false);*/ // hue out of range } } } [VB.Net] Public Shared Sub ConvertHSBToRGB(h As Single, s As Single, v As Single, ByRef r As Single, ByRef g As Single, ByRef b As Single) If s = 0F Then ’ if s = 0 then h is undefined r = v g = v b = v Else Dim hue As Single = System.Convert.ToSingle(h) If h = 360F Then hue = 0F End If hue /= 60F Dim i As Integer = Fix(Math.Floor(System.Convert.ToDouble(hue))) Dim f As Single = hue – i Dim p As Single = v *(1F – s) Dim q As Single = v *(1F – s * f) Dim t As Single = v *(1F – s *(1 – f)) Select Case i Case 0 r = v g = t b = p Case 1 r = q g = v b = p Case 2 r = p g = v b = t Case 3 r = p g = q b = v Case 4 r = t g = p b = v Case 5 r = v g = p b = q Case Else r = 0F g = 0F b = 0F ’Trace.Assert(false); ’ hue out of range End Select End If End Sub ’ConvertHSBToRGB