/// <summary>
/// walks the property path and gets the value of the property on the object 'value'
/// example: path = "Company.Address[1].City"
/// </summary>
/// <param name="value">object to parse the property value from</param>
/// <param name="path">path to the property</param>
public static object FollowPropertyPath(object value, string path)
{
if (value == null) throw new ArgumentNullException("value");
if (path == null) throw new ArgumentNullException("path");
Type currentType = value.GetType();
object obj = value;
foreach (string propertyName in path.Split('.')) // split property path by "."
{
if (currentType != null)
{
PropertyInfo property = null;
int brackStart = propertyName.IndexOf("["); // parsing out if the property is an indexer property
int brackEnd = propertyName.IndexOf("]");
property = currentType.GetProperty(brackStart > 0 ? propertyName.Substring(0, brackStart) : propertyName);
obj = property.GetValue(obj, null);
if (brackStart > 0) // just for indexer properties
{
string index = propertyName.Substring(brackStart + 1, brackEnd - brackStart - 1); // get the index
// determine type of indexer property. extend the following if other types are required
foreach (Type iType in obj.GetType().GetInterfaces())
{
// http://stackoverflow.com/questions/852233/getting-values-of-a-generic-idictionary-using-reflection
if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
{
obj = typeof(ReflectorUtil).GetMethod("GetDictionaryElement")
.MakeGenericMethod(iType.GetGenericArguments())
.Invoke(null, new object[] { obj, index });
break;
}
if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IList<>))
{
obj = typeof(ReflectorUtil).GetMethod("GetListElement")
.MakeGenericMethod(iType.GetGenericArguments())
.Invoke(null, new object[] { obj, index });
break;
}
}
}
// allow for derived properties in the path (property.PropertyType will get the defined type, obj.GetType the actual one)
currentType = obj != null ? obj.GetType() : null; //property.PropertyType;
}
else return null;
}
return obj;
}
public static TValue GetDictionaryElement<TKey, TValue>(IDictionary<TKey, TValue> dict, object index)
{
TKey key = (TKey)Convert.ChangeType(index, typeof(TKey), null);
return dict[key];
}
public static T GetListElement<T>(IList<T> list, object index)
{
return list[Convert.ToInt32(index)];
}
Donnerstag, 17. März 2011
Get the property value by its path
Dienstag, 23. November 2010
WPF Treeview Recursive Expand/Collapse
public static class TreeViewExt
{
/// <summary>
/// Expands/collapses a treeview control recursively. Since for a hierarchical data template, the items will
/// only be generated when displayed - and only then can be expanded, the method attaches an event to the
/// StatusChanged event of the ItemsContainerGenerator and waits until they are in fact generated to recursively
/// call the expand method on these items.
/// </summary>
///
/// <param name="itemsControl"> ItemsControl, can be treeview or treeviewitem </param>
/// <param name="expand"> expand = false collapses, expand = true expands </param>
/// <param name="levelDepth"> for levelDepth = int.MaxValue, the entire tree will be expanded/collapsed.
/// For any other value n of levelDepth, only n levels away from the supplied itemsControl will be expanded
/// or collapsed to. </param>
public static void ExpandRecursively(this ItemsControl itemsControl, bool expand, int levelDepth)
{
// decrease level depth for next recursive call only if levelDepth != int.MaxValue
int depth = levelDepth == int.MaxValue ? levelDepth : levelDepth - 1;
// expand the item
TreeViewItem treeViewItem = itemsControl as TreeViewItem;
if (treeViewItem != null)
treeViewItem.IsExpanded = expand || levelDepth >= 0; // expand, or keep expanded when levelDepth >= 0
// continue if levelDepth is still bigger than 0, or if subitems need to be collapsed
if (levelDepth > 0 || !expand)
{
// get container generator of itemsControl
ItemContainerGenerator itemContainerGenerator = itemsControl.ItemContainerGenerator;
// if containers have already been generated, the subItems can be expanded/collapsed
if (itemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
for (int i = itemsControl.Items.Count - 1; i >= 0; --i)
{
ItemsControl childControl = itemContainerGenerator.ContainerFromIndex(i) as ItemsControl;
if (childControl != null)
childControl.ExpandRecursively(expand, depth);
}
}
// otherwise, we have to wait for the containers to be generated. attach event to listen for status
else
{
EventHandler handler = null; // store in variable, so the handler can be detached
handler = new EventHandler((s, e) =>
{
if (itemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
for (int i = itemsControl.Items.Count - 1; i >= 0; --i)
{
ItemsControl childControl = itemContainerGenerator.ContainerFromIndex(i) as ItemsControl;
if (childControl != null)
childControl.ExpandRecursively(expand, depth);
itemContainerGenerator.StatusChanged -= handler; // detach
}
}
});
itemContainerGenerator.StatusChanged += handler; // attach
}
}
}
}
Freitag, 15. Oktober 2010
Shrink database (SQL Studio 2008)
- Recovery model: Simple
- Auto Shrink: True
Freitag, 9. Oktober 2009
SQL: transfer record from one database to another
/* The following snippet will copy the complete record with Id = 9 from
[databaseName1].[tableName] to [databaseName2].[tableName]*/
INSERT INTO databaseName1.dbo.tableName
SELECT * FROM databaseName2.dbo.tableName
WHERE tableName.Id = 9
Freitag, 19. Juni 2009
Fill Background of a Control with Gradient
/// <summary>
/// Paints a gradient to the Control's background
/// </summary>
/// <param name="ctrl">Control that needs the brush up</param>
/// <param name="color1">e.g. Color.FromArgb(120, 180, 255), or Color.Yellow</param>
/// <param name="color2"></param>
/// <param name="angle">0: horizontal, 45: top-left to bottom-right, etc.</param>
private void PaintGradientBackground(Control ctrl, Color color1, Color color2, float angle)
{
Rectangle rect = new Rectangle(ctrl.Location, ctrl.Size);
System.Drawing.Drawing2D.LinearGradientBrush gradBrush =
new System.Drawing.Drawing2D.LinearGradientBrush(rect, color1, color2, angle);
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage(bmp);
g.FillRectangle(gradBrush, rect);
ctrl.BackgroundImage = bmp;
ctrl.BackgroundImageLayout = ImageLayout.Stretch;
}
Adding Text with different color styles in RichTextBox
/// <summary>
/// Writing to a RichTextBox in different colors should be easy enough. The intiuitional way would be:
/// richTextBox1.Text += someText;
/// richTextBox1.Select(richTextBox1.Find(someText), someText.Length);
/// richTextBox1.SelectionColor = Color.Blue;
/// Which works but gets messed up when other text is added to the RichTextBox.
/// Adding SelectedText instead of just Text does the trick:
/// </summary>
foreach (string ws in WorksheetsRequired)
{
if (this.Worksheets.ContainsKey(ws))
{
string ok = "Worksheet " + ws + " found." + Environment.NewLine;
output.SelectionColor = Color.Green;
output.SelectedText += ok;
}
else
{
string error = "Worksheet " + ws + " could not be found." + Environment.NewLine;
output.SelectionColor = Color.Red;
output.SelectedText += error;
}
// scroll to bottom of rtb
output.SelectionStart = this.richTextBox1.Text.Length;output.ScrollToCaret();
}
Dienstag, 12. Mai 2009
datatable to combobox
''' <summary>
''' Binds class names and captions to combobox
''' </summary>
''' <remarks>The order (DataSource after Diplay- and ValueMember) is important.
''' Changing this will put a DataRow into cbx.SelectedValue instead of a string.</remarks>
Private Sub FillSourceClassComboBox()
Dim dt As New DataTable()
dt.Columns.Add(DC_CLASSCAPTION, System.Type.GetType("System.String"))
dt.Columns.Add(DC_CLASSNAME, System.Type.GetType("System.String"))
Dim classes() As String = Me.GetAgent.GetClassNames()
For Each cls As String In classes
If Not IsNothing(cls) Then
Dim dr As DataRow = dt.NewRow()
dr(DC_CLASSCAPTION) = Me.GetAgent.EvidenceClass(cls).Caption
dr(DC_CLASSNAME) = cls
dt.Rows.Add(dr)
End If
Next
Dim dv As DataView = dt.DefaultView
dv.Sort = DC_CLASSCAPTION
cbxSourceClass.DisplayMember = DC_CLASSCAPTION
cbxSourceClass.ValueMember = DC_CLASSNAME
cbxSourceClass.DataSource = dv
' add handler only now, so method is not executed when binding datasource
AddHandler cbxSourceClass.SelectedIndexChanged, AddressOf cbxSourceClass_SelectedIndexChanged
cbxSourceClass.SelectedValue = Me.CurrentObject.AttributeValue(ATTR_SOURCECLASS)
End Sub
