Since blogger does not have a code tag to support formatting of source code it would be rather troublesome to do all of this manually. Luckily Greg Houston over at http://formatmysourcecode.blogspot.com/ was kind enough to share his web app which processes your source code and outputs html which you can directly paste into your blog. Sure you lose all the pretty colors, but as soon as you paste the code into your editor you get them back anyway.
Many thanks to you, Greg.
zaterdag 3 oktober 2009
Using resourcedictionaries to provide user customization
We start out with a resourcedictionary containing the default values in our App.xaml. This way we can reference the dictionary throughout the entire application.
Let's assume we have a user object which remembers the customizations made by the user. When the user logs in his settings are loaded and all elements referencing the resourcedictionary we defined earlier will display the way the user defined.
Every control referencing the resourcedictionary will display itself differently according to which user is logged in.
<Application.Resources>
<SolidColorBrush x:Key="UserBackgroundColor" Color="White"/>
<SolidColorBrush x:Key="UserControlColor" Color="White"/>
<SolidColorBrush x:Key="UserControlFontColor" Color="Black"/>
<FontFamily x:Key="UserControlFont">Segoe UI</FontFamily>
</Application.Resources>
Let's assume we have a user object which remembers the customizations made by the user. When the user logs in his settings are loaded and all elements referencing the resourcedictionary we defined earlier will display the way the user defined.
private void MergeDictionaries(User user)
{
ResourceDictionary resourceDictionary = new ResourceDictionary();
SolidColorBrush userBackgroundColor = new SolidColorBrush(Colors.White);
if (user.BackgroundColor != null)
{
userBackgroundColor = user.BackgroundColor;
}
resourceDictionary.Add("UserBackgroundColor", userBackgroundColor);
SolidColorBrush userControlColor = new SolidColorBrush(Colors.White);
if (user.ControlColor != null)
{
userControlColor = user.ControlColor;
}
resourceDictionary.Add("UserControlColor", userControlColor);
SolidColorBrush userControlFontColor = new SolidColorBrush(Colors.Black);
if (user.ControlFontColor != null)
{
userControlFontColor = user.ControlFontColor;
}
resourceDictionary.Add("UserControlFontColor", userControlFontColor);
FontFamily userControlFont = new FontFamily("Segoe UI");
if (user.ControlFont != null && !user.ControlFont.Equals(""))
{
userControlFont = new FontFamily(user.ControlFont);
}
resourceDictionary.Add("UserControlFont", userControlFont);
Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
}
Every control referencing the resourcedictionary will display itself differently according to which user is logged in.
<TextBlock Name="txtText"
Foreground="{StaticResource UserControlFontColor}"
FontFamily="{StaticResource UserControlFont}"
Text="Text"/>
Creating a form with moveable controls
This is part of a larger concept that involves letting users design the layout of the forms they use themselves (adding, (re)moving and saving controls). The basic setup is a canvas with stackpanels as its children which can be moved around freely. The stackpanels can contain any kind and amount of children or you can replace the stackpanels with another frameworkelement of your liking.
XAML:
These three handlers handle the dragging of controls around the canvas:
Because a canvas has no support for sizing to its children, of course there would be problems when moving around its children inside and outside of its boundaries. The following piece of code is called when you release the mouse on the control you're dragging and recalculates the canvas' dimensions. This way the scrollviewer around the canvas can display scrollbars when needed.
This method makes the control you're dragging the topmost one among the canvas' children so you're not dragging the control around below others.
Finally this method is used to provide snapping functionality to more easily align your controls on the canvas. It searches for controls positioned within the proximity of the control being moved. The snap distance determines how many pixels you must move your mouse cursor at once to 'snap out' of the hold again.
XAML:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Name="canvasControls"/>
</ScrollViewer>
These three handlers handle the dragging of controls around the canvas:
private void controls_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
position = e.GetPosition(canvasControls);
StackPanel panel = (StackPanel)sender;
if (editMode)
{
panel.CaptureMouse();
}
panel.Tag = true;
SetZIndex(panel);
}
private void controls_PreviewMouseMove(object sender, MouseEventArgs e)
{
StackPanel panel = (StackPanel)sender;
if (e.LeftButton == MouseButtonState.Pressed && editMode && (bool)panel.Tag)
{
Point currentPosition = e.GetPosition(canvasControls);
double moveX = currentPosition.X - position.X;
double moveY = currentPosition.Y - position.Y;
double newX = Canvas.GetLeft(panel) + moveX;
double newY = Canvas.GetTop(panel) + moveY;
FrameworkElement element = SnapToControl(panel, newX, true);
if (element != null)
{
newX = Canvas.GetLeft(element);
}
element = SnapToControl(panel, newY, false);
if (element != null)
{
newY = Canvas.GetTop(element);
}
Canvas.SetLeft(panel, newX);
Canvas.SetTop(panel, newY);
position = currentPosition;
}
}
private void controls_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
StackPanel panel = (StackPanel)sender;
panel.Tag = false;
panel.ReleaseMouseCapture();
RedrawCanvas(panel);
}
Because a canvas has no support for sizing to its children, of course there would be problems when moving around its children inside and outside of its boundaries. The following piece of code is called when you release the mouse on the control you're dragging and recalculates the canvas' dimensions. This way the scrollviewer around the canvas can display scrollbars when needed.
private void RedrawCanvas(FrameworkElement element)
{
double minTop = 0;
double minLeft = 0;
double maxTop = 0;
double maxLeft = 0;
foreach (FrameworkElement control in canvasControls.Children)
{
double top = Canvas.GetTop(control);
double left = Canvas.GetLeft(control);
if (top < minTop)
{
minTop = top;
}
if (top > maxTop)
{
maxTop = top;
}
if (left < minLeft)
{
minLeft = left;
}
if (left > maxLeft)
{
maxLeft = left;
}
}
if (minTop < 0)
{
foreach (FrameworkElement control in canvasControls.Children)
{
Canvas.SetTop(control, Canvas.GetTop(control) + Math.Abs(minTop));
}
}
if (minLeft < 0)
{
foreach (FrameworkElement control in canvasControls.Children)
{
Canvas.SetLeft(control, Canvas.GetLeft(control) + Math.Abs(minLeft));
}
}
canvasControls.Width = maxLeft + element.Width;
canvasControls.Height = maxTop + element.Height;
}
This method makes the control you're dragging the topmost one among the canvas' children so you're not dragging the control around below others.
private void SetZIndex(FrameworkElement control)
{
int z = 0;
foreach (FrameworkElement element in canvasControls.Children)
{
if (!element.Name.Equals(control.Name))
{
Canvas.SetZIndex(element, z++);
}
}
Canvas.SetZIndex(control, z);
}
Finally this method is used to provide snapping functionality to more easily align your controls on the canvas. It searches for controls positioned within the proximity of the control being moved. The snap distance determines how many pixels you must move your mouse cursor at once to 'snap out' of the hold again.
private FrameworkElement SnapToControl(FrameworkElement sender, double newPosition, bool x)
{
double snapDistance = Properties.Settings.Default.snap;
foreach (FrameworkElement element in canvasControls.Children)
{
if (!element.Name.Equals(sender.Name))
{
double difference = 0;
switch (x)
{
case true:
difference = Canvas.GetLeft(element) - newPosition; break;
case false:
difference = Canvas.GetTop(element) - newPosition; break;
}
difference = Math.Abs(difference);
if (difference <= snapDistance && difference > 0)
{
return element;
}
}
}
return null;
}
Get a table's primary keys
DataSet data = new DataSet();
SqlConnection connection = new SqlConnection(Properties.Settings.Default.connectionString);
SqlCommand command = new SqlCommand();
string commandtext = "SELECT TOP 1 * FROM " + tabelName;
command.CommandText = commandtext;
command.Connection = connection;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.FillSchema(data, SchemaType.Source);
DataColumn[] pks = data.Tables[0].PrimaryKey;
Get table names of all tables containing a given column
DataSet dsTableNames = new DataSet();
SqlConnection connection = new SqlConnection(Properties.Settings.Default.connectionString);
SqlCommand command = new SqlCommand();
string commandtext = "SELECT sys.sysobjects.name " +
"FROM sys.sysobjects INNER JOIN " +
"sys.syscolumns ON sys.sysobjects.id = sys.syscolumns.id " +
"WHERE (sys.syscolumns.name = @Column)";
command.CommandText = commandtext;
command.Parameters.Add(new SqlParameter("@Column", columnName));
command.Connection = connection;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(dsTableNames, "tableNames");
Get column names from a SQL table
DataTable dtColumnNames = new DataTable();
SqlCommand command = new SqlCommand();
SqlConnection connection = GetConnection();
string commandText = "SELECT name FROM sys.syscolumns WHERE (id = OBJECT_ID(@Table))";
command.Connection = connection;
command.CommandText = commandText;
command.Parameters.Add(new SqlParameter("@Table", tableName));
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(dtColumnNames);
Programmatically creating an email in Outlook 2007
This code creates a new email object, reads an html file to set as its body, adds any attachments from a list of filenames and saves it in the drafts folder of your Outlook client.
using Outlook = Microsoft.Office.Interop.Outlook;
Outlook.Application otlApp = new Outlook.Application();
Outlook._MailItem otlMail = (Outlook._MailItem)otlApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
otlMail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
string html = "";
System.IO.Stream stream = File.OpenRead(filename);
System.IO.StreamReader reader = new System.IO.StreamReader(stream);
html = reader.ReadToEnd();
reader.Close();
otlMail.HTMLBody = html;
object oAttachType = Outlook.OlAttachmentType.olByReference;
foreach (string attachmentPath in attachmentPaths)
{
Outlook.Attachment oAttach = otlMail.Attachments.Add(attachmentPath, oAttachType, oMissing, oMissing);
}
otlMail.Display(false);
otlMail.Save();
Reading a file from a SQL BLOB column
Counterpart to the previous post.
Byte[] output = new Byte[255];
long blob = 0;
FileStream stream;
BinaryWriter writer;
SqlConnection connection = DatabaseManager.GetConnection();
string commandText = "SELECT Name, Extension, Blob FROM tablename WHERE FileId=@Id";
SqlCommand command = new SqlCommand(commandText, connection);
command.Connection = connection;
command.CommandText = commandText;
command.Parameters.Add(new SqlParameter("@Id", fileId));
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
string fileName = "";
string fileExtension = "";
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
while (reader.Read())
{
fileName = reader.GetString(0);
fileExtension = reader.GetString(1);
string path = filePath + @"\" + fileName + fileExtension;
stream = new FileStream(pad, FileMode.OpenOrCreate, FileAccess.Write);
writer = new BinaryWriter(stream);
long startIndex = 0;
blob = reader.GetBytes(2, startIndex, output, 0, 255);
while (blob == 255)
{
writer.Write(output);
writer.Flush();
startIndex += 255;
blob = reader.GetBytes(2, startIndex, output, 0, 255);
}
writer.Write(output, 0, (int)blob);
writer.Flush();
writer.Close();
stream.Close();
}
Inserting a file into a SQL BLOB column
One way to insert files into an SQL database. The file can be anything, an image, word document, etc. Just change the extension to your liking.
SqlCommand command = new SqlCommand();
SqlConnection connection = DatabaseManager.GetConnection();
string commandText = "INSERT INTO tablename VALUES(@Name, @Extension, @Blob)";
command.Connection = connection;
command.CommandText = commandText;
command.Parameters.Add(new SqlParameter("@Name ", fileName));
command.Parameters.Add(new SqlParameter("@Extension ", fileExtension));
FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
Byte[] blob = new Byte[stream.Length];
stream.Read(blob, 0, blob.Length);
stream.Close();
stream.Dispose();
command.Parameters.Add(new SqlParameter("@Blob", blob));
command.ExecuteNonQuery();
Abonneren op:
Reacties (Atom)