Showing posts with label c# tip of the day. Show all posts
Showing posts with label c# tip of the day. Show all posts

Wednesday, December 10, 2008

[C#] Loading embedded XAML files into a project

I was looking for a way to load in a XAML file into my project; I wanted to be able to create a nice looking element without having to build it up dynamically in the C# code, and without having to download the XAML file from a server as I have been doing in some other places.

Turns out you can embed a file as a resource in a Visual Studio project and then open the resource and stream it out!
Step 1: Right click on your project folder and add the new or existing resource to your project.

Step 2: Right click the newly added file in your solution explorer, and select "Properties"

Step 3: Change the "Build Action" to "Embedded Resource". Now the file will be built in to your project as a resource and accessible as such.

Step 4: Open up a stream to the resource, read it out into a string and then use XAMLReader.Load to load up the element. I found this code on a forum, so there may be an easier way to do it... but this worked for me.

Stream s = this.GetType().Assembly.GetManifestResourceStream ("myNamespace.myFile.xaml");
string propertyStr = new StreamReader(s).ReadToEnd();
Panel myGrid = (Panel)XamlReader.Load(propertyStr);

And BAM... loaded xaml! Note that your XAML file must contain the namespace information in order for [System.Windows.Markup.]XAMLReader.Load to load correctly.

Example myFile.xaml:
<. Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<. /Grid .>


Have fun :)
.

Friday, October 10, 2008

[C#] Object Creation with Property Initialization

So a colleague of mine showed me a nice simple way in C# to both create and initialize an object in one step. I thought this was really neat syntax since it both saves lines of code and also saves some execution as the object is initialized with a value instead of a default which is THEN changed.

So something like this:
Rectangle myRec = new Rectangle();
myRec.Width = 50;
myRec.Height = 50;
Can become:
Rectangle myRec = New Rectangle() { Width=50, Height=50 };


There are some restrictions though:
  • Can only initialize properties or fields accessible by the object being initialized.
  • This means that you cannot set attached properties in this manner [ie. Canvas.Top], as these properties can only be set with the SetValue function.
  • The assignments in the initializer is treated the same as assignments to members of the field/property.

See here for a little more
And this msdn page

.

Tuesday, June 3, 2008

[C#, WPF] Dependency Properties, Objects and Attached Properties [Oh my!]

Ok wow... I opened up a can of worms looking up "attached properties" this morning. I need another coffee. Here goes though - it appears that WPF introduced a few new key concepts, including Dependency Properties [and thus Dependency Objects, and Attached Properties].

Dependency Properties
Dependency Properties [called DPs from now on because I am lazy] were introduced throughout the WPF platform to help enable styling, databinding, animation and more. Quite literally, a DP depends on multiple different providers to determine it's value at any given point in time. The main reason behind this structure is to allow for rich functionality to be enabled directly from the markup [XAML] instead of relying on any procedural code.

Because of this 'dynamic determination of values', the WPF infrastructure must be setup to know and deal with DPs correctly. DPs have a very specific implementation structure that must be adhered to if one wishes to create a DP. They have a special naming convention ( [propertyName]Property --> MyDPProperty) and are public static. They must be registered so that WPF knows how to perform the callbacks when specific events occur on the property. I'm not going to go into the details of registering a DP as it is a little more in depth then I'd like to go today, but please see my links below for more info.

Excellent Reference for DPs [en.csharp-online.net]


Dependency Objects
If creating class that you wish to add DPs to, you must derive from DependencyObject so that WPF knows to enable it's property system services on it. The property system service is what WPF uses to calculate the value of a dependency property based on the multiple providers that may exist for a DP.

My focus for today is more on the DPs and attached properties, so I will leave any explaination about DO's short... namely because *I* haven't really read up on them in much detail ;)

MSDN DependencyObject
Support for multiple providers


Attached Properties
Finally... this is where I started. An Attached Property [AP] is a special form of a DP that can be attached to arbitrary objects that may not actually support the given property. Sounds weird right? It makes more sense when you look at the use of these properties to give styles to an element and it's associated children via "property value inheritance".

The term property value inheritance (or property inheritance for short) doesn't refer to traditional object oriented class-based inheritance, but rather the
flowing of property values down the element tree.

So in other words, if you set a property in a parent element, the children will also recieve the same value unless specifically specified in the child element. But what happens if you wish to set up this property inheritance on a parent object that doesn't natively support that property? Say you have a StackPanel and you want all children of the StackPanel to have the same FontSize? This is where attached properties because very useful.

< StackPanel TextElement.FontSize="22" >
< Button >Button1 </Button >
< Button >Button2 </Button >
< Button >Button3 </Button >
</ StackPanel >


All buttons will have FontSize of 22 since none have been overridden.

For this to work, an attached property provider must be used [in this case TextElement], which provides access to the get/set accessors for the attached property. Calls to the Get/SetValue methods are actually applied on the passed-in DependancyObject, rather then the current instance. [Ie. on TextElement, not on StackPanel].

The all too familiar property of Canvas.Left/Top on elements such as a Rectangle [if I am understanding this correctly] is actually an attached property then! This makes more sense now looking at how things are syntactically set up.

Again, there are more complexities with attached properties to go into but I am not going that deep today. Need to let all this sink in first :)

Attached Properties [en.csharp-online.net]

Monday, June 2, 2008

[C#] Using TooltipService

NOTE: As of Silverlight 2 Beta 2, this seems to be borked. Not sure why yet... I'll have a look later.

Today I was trying to add a simple tooltip to a bunch of small Canvas' in my Silverlight project. After a little digging I found that
  • (a) there is a .NET class called Tooltip which does this functionality for me and
  • (b) many controls lack a ToolTip property [such as TextBox, TextBlock, Canvas etc...]
To add a ToolTip to these controls, we are able to use the ToolTip attached property via ToolTipService. I am unfamiliar with attached properties, and I will be going over them in detail soon, however, for now I'm just going to drone on about using the ToolTipService in C# since it took me a little digging to find any kind of example [most were examples in XAML only].
  // Create a Tooltip
ToolTip nameTip = new ToolTip();

// Set the content [here I use text, but apparently it can be more complex]
nameTip.Content = "Testing ToolTipService";

// Use ToolTipService to attach the ToolTip to my Canvas.
ToolTipService.SetToolTip(myCanvas, nameTip);
Note, you may need to add the System.Windows.Controls reference to your project for this to work... I can't recall if that assembly is added by default when you create a project in VS2008.

ToolTipService Documentation

Monday, May 26, 2008

[C#] Accessors - get and set cleanliness

While looking at some example code, I bumped into some syntax that looked like a shorthand for declaring get and set methods for a given property - and I thought "well hey, isn't that cool".

Turns out that in C#, this is exactly the case...

"The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both."

Instead of writing something like this which I do all the time:
class myClass
{
private int myProp;
public void getMyProp() { return myProp; }
public void setMyProp(int newProp) { myProp = newProp; }
}
We can do this in C#:
class myClass
{
private int myProp;
pubic int MyProp
{
get { return myProp; }
set { myProp = value; }
}
}
This is a little cleaner and allows us to access the get and set functionality in a very straight forward manner:
  • int whee = myClassInstance.myProp;
    • instead of --> int whee = myClassInstance.getMyProp();
  • myClassInstance.myProp = 22
    • instead of --> myClassInstance.setMyProp(22);
A few things to note:
  • Both the private property, and the public property containing the accessor functions may have very similar names, but do not confuse them.
  • May contain only set [write], only get [read] or both [read/write].
  • The 'value' seen in the set accessor is a C# keyword. It is a free variable that is created by the complier, and no other variables within the set accessor may share that name [duh].
  • There's more to it when talking about inheritance and abstract classes, but perhaps I'll save that for another day.
  • Can also be done for a public member variable, although to me this seems a little silly since you can directly access a public variable anyways. I just added this to show that the syntax was possible.
    class myClass
    {
    public myPublicProp
    {
    get { return myPublicProp; }
    set { myPublicProp = value; }
    }
    }

MSDN Documentation

Thursday, May 22, 2008

[C#] Nullable Types

I bumped into this in my web travels today: Nullable types. Introduced in the 2.0 .NET framework was the ability to represent the normal range of values for a given value type PLUS the null value.

Nullable types can only be VALUE types [including structs]. It cannot be applied to reference types. Syntactically they look as follows:
  • T? // Is actually shorthand for...
  • System.Nullable // A struct - see below for its properties.


Ex. int? or System.Nullable

The nullable struct brings with it two readonly properties:
  • HasValue: Returns true if the variable contains a value, and false if null.
    • ex. Can use (x.HasValue) or (x != null) pretty much interchangeably.
  • Value: Returns the value if one is assigned or throws an InvalidOperationException if not assigned. Often this function is used to help cast a nullable type to a non nullable type.
ex.
// Correct
int? iNull = null;

// Will not compile
int notNull = iNull;

// Will compile, but exc thrown if null.
int notNull2 = iNull.Value;


When using operators on nullable values, the result will be a null if any of the operands are null. When comparing nullables, if one of the values is null then the comparison is always FALSE.

Often used with Nullable types is the ?? operator. It returns the left-hand operand if it is not null, or else it returns the right operand.

int? iNull = null; int iNull2 = null;

// notNull will receive the value -1.
int notNull = iNull ?? -1;

// Can use the ?? multiple times...
int notNull2 = iNull ?? iNull2 ?? -1;


If using bool? then the variable may not be used in conditionals like if, or for. The code will not compile.

Reference MSDN

Wednesday, May 21, 2008

[C#] More on string concatenation - String.Join

After yesterday's post about "+=" vs StringBuilder, I did a little more looking around on the topic of string concatenation. It appears that if you can get the strings you wish to concatenate into an array then the String.Join(string, string[], int, int) method is actually faster then the StringBuilder.Append method.
public static string Join(
string separator,
string[] value,
int startIndex,
int count
)
Now, in my case, I have a dynamic number of strings I am concatenating together - so using String.Join is a little trickier because I seemingly have to create a List first and then copy over to a String[] before I can use the String.Join method.

My Test - String.Join vs. StringBuilder.Append vs. "+="
I was curious about this, wondering if those intermediate steps would slow things down enough to make String.Join worse than StringBuilder in efficiency... so I wrote up a small little test with timing:
...
int[] numStrings = { 100, 1000, 10000, 20000, 30000 };
foreach (int num in numStrings)
{
output += "*** NUM STRINGS = " + num.ToString() + " ***\r\n";

//---------------------------------
// String.Join
//---------------------------------
start = DateTime.Now;
poo = new List();
for (int i = 0; i < num; i++)
{
poo.Add("poo");
}
newArr = new String[poo.Count];
poo.CopyTo(newArr);
allPoo = String.Join(" ", newArr);
end = DateTime.Now;
diff = end.Subtract(start);
//---------------------------------
start = DateTime.Now;
output += "String.Join: " + diff.ToString() + "\r\n";

//---------------------------------
// StringBuilder.Append
//---------------------------------
newBuilder = new System.Text.StringBuilder();
for (int i = 0; i < num; i++)
{
newBuilder.Append("poo ");
}
end = DateTime.Now;
diff = end.Subtract(start);
//---------------------------------
start = DateTime.Now;
output += "StringBuilder: " + diff.ToString() + "\r\n";

//---------------------------------
// +=
//---------------------------------
myString = "";
for (int i = 0; i < num; i++)
{
myString += "poo ";
}
end = DateTime.Now;
diff = end.Subtract(start);
//---------------------------------
start = DateTime.Now;
output += "+=: " + diff.ToString() + "\r\n";
}
this.oam.addMessage(output);

To which the output was:
*** NUM STRINGS = 100 ***
String.Join: 00:00:00.2031224
StringBuilder: 00:00:00
=: 00:00:00

*** NUM STRINGS = 1000 ***
String.Join: 00:00:00
StringBuilder: 00:00:00
=: 00:00:00.0156248

*** NUM STRINGS = 10000 ***
String.Join: 00:00:00.0156248
StringBuilder: 00:00:00
=: 00:00:01.1249856

*** NUM STRINGS = 20000 ***
String.Join: 00:00:00.0156248
StringBuilder: 00:00:00
=: 00:00:06.5311664

*** NUM STRINGS = 30000 ***
String.Join: 00:00:00.0156248
StringBuilder: 00:00:00.0156248
=: 00:00:16.1404184

So as you can see in this test:
  • StringBuilder.Append only becomes more efficient then String.Join after 1000 strings, although even then the two seem very close in efficiency.
  • "+=" is the least efficient of the group, although it really only becomes noticeable after 1000 strings
My Conclusions
  • I'll probably try to use String.Join where ever possible when doing my large string concatenations, even if I have to place all the strings into a List before I use the method.





Tuesday, May 20, 2008

[C#] Efficient String Concatenation - "+=" vs StringBuilder

Again, in my short C# travels, I find myself very very often doing dynamic string concatenations. One major task I have tried to do is create a basic serialization function for XAML elements, so that I can store/save a XAML element to the server in my project. I thus end up doing many, many string concatenations.

Using "+=" to Concat
So often I end up doing this...:

String newStr = "";
if ([prop] != null) { newStr += "[prop]= " + obj.getValue([prop]).toString(); }

...for many, many properties. When actually compiled, every time the "+=" concatenation is used, an entirely new string must be created to hold the 'new' complete string. This can become very inefficient and slow if you do a large number of such string concats.


Using StringBuilder

What I didn't know about, was the StringBuilder class. Found under the System.Text library, StringBuilder maintains an internal buffer to which [via the function StringBuilder.Append()] will append to; thus a new string will not be created every time an append occurs. If the internal buffer is exceeded THEN a new buffer size will be allocated.

Thus the usage of StringBuilder *CAN* be more efficient then using "+=". Note that more overhead is needed to create and manage the StringBuilder object, so in all cases, StringBuilder will *NOT* be absolutely more efficient. It really depends on the size of the strings and the frequency of the concats.

General Rule of Thumb
  • If the concats can fit into one statement [or only a few statements], then the "+=" is probably the safest route to take.
  • If you have multiple long, or a dynamic amount of string concats, then StringBuilder may be able to increase efficiency.

Reference: www.yoda.archsys.com

Friday, May 16, 2008

[C#] More about Typecasting with 'as' and 'is'

Taken from this CodeGuru article I found by Jay Miller

Often in my programming experiences with C# I want to check if an object is a specific type without throwing a code stopping exception. So I end up writing something very similar to this:

if (myObject.GetType().ToString().Name == "Canvas")
{
// Wicked code goes here.
}

or

Canvas myCanvas = myObject as Canvas; // If invalid typecast this will return null.
if (myCanvas != null)
{
// Wicked code goes here.
}

I've found a slightly cleaner way to accomplish this:

Canvas myCanvas = myObject as Canvas;
if (myCanvas is Canvas)
{
// Wicked code goes here.
}

The change is subtle, but I think that it makes this comparison much more clear and easy to read. Also, according to the referenced article, this comparison via 'is' is slightly more efficient then comparing against null.

Thursday, May 15, 2008

[C#] Parameter Passing - "ref" and "out"

Before I get into parameter passing...

There are two different types in C#
1) Value-Types [http://msdn2.microsoft.com/en-us/library/s1ax56ch(VS.71).aspx]
- Structs
* Built in --> Numeric Types [int, double etc...], Bool.
* User defined
- Enums
- Unlike reference types, it is not possible for a value type to contain the null value.
2) Reference-Types [http://msdn2.microsoft.com/en-us/library/490f96s2(VS.71).aspx <-- seems to be broken]
- class, delegate, interface, object, string.
Parameter Passing
All value-type parameters are what we call "pass by value" and all changes made to that value in the function will have no affect on the original data.
All reference-type parameters are "pass by reference" and all changes made to it will be reflected in the original.
If you want to force a parameter to be pass by reference then we use the "ref" or "out" keyword.
Differences Between "ref" and "out"
"out": an out parameter of an array type must be assigned before it is used; that is, it must be assigned by the callee.
For example:
public static void MyMethod(out int[] arr)
{
arr = new int[10]; // definite assignment of arr
}
C#
"ref": a ref parameter of an array type must be definitely assigned by the caller. Therefore, there is no need to be definitely assigned by the callee. A ref parameter of an array type may be altered as a result of the call. For example, the array can be assigned the null value or can be initialized to a different array.
For example:
public static void MyMethod(ref int[] arr)
{
arr = new int[10]; // arr initialized to a different array
}

Wednesday, May 14, 2008

[C#] Explicit Typecasting - ( ) vs "as"

One thing that confused me when starting out, was the seemingly intangible difference between typecasting via ([type])object and object as [Type]. With a small amount of digging here is what I found.

Two Methods of Explicit Typecasting

- Will raise an exception if the typecast is not valid.
- Seems to have slightly more overhead in execution time [(1)][(2)]
- Works well with classic value types [int, double] [(1)]
- Will return null if the typecast is not valid.
- Seems to have slightly less overhead in execution time.
- Only works for reference conversions and boxing conversions [(1)]
* Note: I believe the following is "boxing":
int myInt = 4;
Object myObj = myInt; // <-- now myInt is boxed into myObj.
int testInt = myObj as int // <-- can do this with as operator.
References: