Tải bản đầy đủ - 0 (trang)
16-14. Create Custom LINQ Extension Methods

16-14. Create Custom LINQ Extension Methods

Tải bản đầy đủ - 0trang

CHAPTER 16 ■ USING LINQ



The Code

The following example demonstrates creating a customer LINQ extension method that removes the first

and last element from string data sources:

using

using

using

using



System;

System.Collections.Generic;

System.Linq;

System.Text;



namespace Apress.VisualCSharpRecipes.Chapter16

{

static class LINQExtensions

{

public static IEnumerable RemoveFirstAndLast(

this IEnumerable source)

{

return source.Skip(1).Take(source.Count() - 2);

}

}

class Recipe16_14

{

static void Main(string[] args)

{

// Create the data sources.

string[] ds1 = {"apple", "banana", "pear", "fig"};

IList ds2 = new List

{ "apple", "banana", "pear", "fig" };

Console.WriteLine("Extension method used on string[]");

IEnumerable result1 = ds1.RemoveFirstAndLast();

foreach (string element in result1)

{

Console.WriteLine("Result: {0}", element);

}

Console.WriteLine("\nExtension method used on IList");

IEnumerable result2 = ds1.RemoveFirstAndLast();

foreach (string element in result2)

{

Console.WriteLine("Result: {0}", element);

}

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter");

Console.ReadLine();

}

}

}



783



www.it-ebooks.info



CHAPTER 16 ■ USING LINQ



Running the sample program gives the same result for the differing data sources:

Extension method used on string[]

Result: banana

Result: pear



Extension method used on IList

Result: banana

Result: pear



Main method complete. Press Enter



16-15. Convert from IEnumerable<>

Problem

You want to use the results of a LINQ query in a form other than an enumeration.



Solution

Use one of the LINQ convenience extension methods to convert your result.



How It Works

It is not always convenient to have the results of a query as an IEnumerable. LINQ provides a series of

extension methods that you can use to convert a query result into different types.



The Code

The following example creates a data source containing instances of the type Fruit, performs a LINQ

query to select those with a short shelf life, and then converts the result to an array, a Dictionary, a List,

and a Lookup, printing out the contents of each:



784



www.it-ebooks.info



CHAPTER 16 ■ USING LINQ



using

using

using

using



System;

System.Collections.Generic;

System.Linq;

System.Text;



namespace Apress.VisualCSharpRecipes.Chapter16

{

class Recipe16_15

{

static void Main(string[] args)

{

// Create the data sources.

IEnumerable datasource = createData();

// Perform a query.

IEnumerable result = from e in datasource

where e.ShelfLife <= 7

select e;

// Enumerate the result elements.

Console.WriteLine("Results from enumeration");

foreach (Fruit fruit in result)

{

Console.WriteLine("Name: {0} Color: {1} Shelf Life: {2} days.",

fruit.Name, fruit.Color, fruit.ShelfLife);

}

// Convert the IEnumerable to an array.

Fruit[] array = result.ToArray();

// print out the contents of the array

Console.WriteLine("\nResults from array");

for (int i = 0; i < array.Length; i++)

{

Console.WriteLine("Name: {0} Color: {1} Shelf Life: {2} days.",

array[i].Name,

array[i].Color, array[i].ShelfLife);

}

// Convert the IEnumerable to a dictionary indexed by name.

Dictionary dictionary = result.ToDictionary(e => e.Name);

// print out the contents of the dictionary

Console.WriteLine("\nResults from dictionary");

foreach (KeyValuePair kvp in dictionary)

{

Console.WriteLine("Name: {0} Color: {1} Shelf Life: {2} days.",

kvp.Key, kvp.Value.Color, kvp.Value.ShelfLife);

}



785



www.it-ebooks.info



CHAPTER 16 ■ USING LINQ



// Convert the IEnumerable to a list.

IList list = result.ToList();

// print out the contents of the list

Console.WriteLine("\nResults from list");

foreach (Fruit fruit in list)

{

Console.WriteLine("Name: {0} Color: {1} Shelf Life: {2} days.",

fruit.Name, fruit.Color, fruit.ShelfLife);

}

// Convert the IEnumerable to a lookup, indexed by color.

ILookup lookup = result.ToLookup(e => e.Color);

// Print out the contents of the list.

Console.WriteLine("\nResults from lookup");

IEnumerator> groups = lookup.GetEnumerator();

while (groups.MoveNext())

{

IGrouping group = groups.Current;

Console.WriteLine("Group for {0}", group.Key);

foreach (Fruit fruit in group)

{

Console.WriteLine("Name: {0} Color: {1} Shelf Life: {2} days.",

fruit.Name, fruit.Color, fruit.ShelfLife);

}

}

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter");

Console.ReadLine();

}

static IList createData()

{

return new List()

{

new Fruit("apple", "red", 7),

new Fruit("orange", "orange", 10),

new Fruit("grape", "green", 4),

new Fruit("fig", "brown", 12),

new Fruit("plum", "red", 2),

new Fruit("banana", "yellow", 10),

new Fruit("cherry", "red", 7)

};

}

}

class Fruit

{



786



www.it-ebooks.info



CHAPTER 16 ■ USING LINQ



public Fruit(string namearg, string colorarg, int lifearg)

{

Name = namearg;

Color = colorarg;

ShelfLife = lifearg;

}

public string Name { get; set; }

public string Color { get; set; }

public int ShelfLife { get; set; }

}

}

Running the program gives the following results:

Results from enumeration

Name: apple Color: red Shelf Life: 7 days.

Name: grape Color: green Shelf Life: 4 days.

Name: plum Color: red Shelf Life: 2 days.

Name: cherry Color: red Shelf Life: 7 days.



Results from array

Name: apple Color: red Shelf Life: 7 days.

Name: grape Color: green Shelf Life: 4 days.

Name: plum Color: red Shelf Life: 2 days.

Name: cherry Color: red Shelf Life: 7 days.



Results from dictionary

Name: apple Color: red Shelf Life: 7 days.

Name: grape Color: green Shelf Life: 4 days.

Name: plum Color: red Shelf Life: 2 days.

Name: cherry Color: red Shelf Life: 7 days.



787



www.it-ebooks.info



CHAPTER 16 ■ USING LINQ



Results from list

Name: apple Color: red Shelf Life: 7 days.

Name: grape Color: green Shelf Life: 4 days.

Name: plum Color: red Shelf Life: 2 days.

Name: cherry Color: red Shelf Life: 7 days.



Results from lookup

Group for red

Name: apple Color: red Shelf Life: 7 days.

Name: plum Color: red Shelf Life: 2 days.

Name: cherry Color: red Shelf Life: 7 days.

Group for green

Name: grape Color: green Shelf Life: 4 days.



Main method complete. Press Enter



788



www.it-ebooks.info



C H A P T E R 17

■■■



Windows Presentation

Foundation

Windows Presentation Foundation (WPF), introduced in the .NET Framework 3.0, provides an

alternative to Windows Forms (see Chapter 7) for the development of highly functional rich client

applications. The WPF development model is radically different than that of Windows Forms and can be

difficult to adjust to—especially for experienced Windows Forms developers. However, WPF is

incredibly flexible and powerful, and taking the time to learn it can be lots of fun and immensely

rewarding. WPF enables the average developer to create user interfaces that incorporate techniques

previously accessible only to highly specialized graphics developers and take a fraction of the time to

develop that they would have once taken.

The capabilities offered by WPF are immense, so it is not possible to provide full coverage here. A far

more extensive set of recipes about WPF is provided in WPF Recipes in C# 2010 (Apress, 2010), of which

the recipes in the chapter are a much simplified subset. Thanks to Sam Bourton and Sam Noble for the

original work on some of the recipes in this chapter. The recipes in this chapter describe how to do the

following:





Create and use a dependency and attached properties (recipes 17-1 and 17-2)







Define and use application-wide resources (recipe 17-3)







Debug data bindings (recipes 17-4 and 17-5)







Control the position of UI elements using layout containers (recipes 17-6

through 17-9)







Get rich text input from the user (recipe 17-10)







Display a control rotated (recipe 17-11)







Create and configure user controls (recipes 17-12 through 17-14)







Create two-way and command bindings (recipes 17-15 and 17-16)







Use data templates to display bound data (recipe 17-17)







Bind controls to a master-detail collection (recipe 17-18)







Change a control’s appearance when the mouse goes over it (recipe 17-19)



789



www.it-ebooks.info



CHAPTER 17 ■ WINDOWS PRESENTATION FOUNDATION







Make alternate items in a list look different (recipe 17-20)







Allow the user to drag items from a list and position them on a canvas (recipe

17-21)







Show progress and allow cancellation of a long-running process (recipe 17-22)







Draw and reuse two-dimensional shapes (recipes 17-23 and 17-24)







Fill shapes with colors, gradients, images, and textures (recipes 17-25 through

17-28)







Animate the properties of a control (recipes 17-29 through 17-32)







Play a media file (recipe 17-33)







Query the state of the keyboard (recipe 17-34)



17-1. Create and Use a Dependency Property

Problem

You need to add a property to a class that derives from System.Windows.DependencyObject to provide

support for any or all of the following:





Data bindings







Animation







Setting with a dynamic resource reference







Automatically inheriting a property value from a superclass







Setting in a style







Using property value inheritance







Notification through callbacks on property value changes



Solution

Register a System.Windows.DependencyProperty to use as the backing store for the required property on

your class.



790



www.it-ebooks.info



CHAPTER 17 ■ WINDOWS PRESENTATION FOUNDATION



How It Works

A dependency property is implemented using a standard Common Language Runtime (CLR) property,

but instead of using a private field to back the property, you use a DependencyProperty. A

DependencyProperty is instantiated using the static method DependencyProperty.Register(string name,

System.Type propertyType, Type ownerType), which returns a DependencyProperty instance that is

stored using a static, read-only field. There are also two overrides that allow you to specify metadata that

defines behavior and a callback for validation.

The first argument passed to the DependencyProperty.Register method specifies the name of the

dependency property being registered. This name must be unique within registrations that occur in the

owner type’s namespace. The next two arguments give the type of property being registered and the

class against which the dependency property is being defined. It is important to note that the owning

type must derive from DependencyObject; otherwise, an exception is raised when you initialize the

dependency property.

The first override for the Register method allows a System.Windows.PropertyMetadata object, or one

of the several derived types, to be specified for the property. Property metadata is used to define

characteristics of a dependency property, allowing for greater richness than simply using reflection or

common CLR characteristics. The use of property metadata can be broken down into three areas:





Specifying a default value for the property







Providing callback implementations for property changes and value coercion







Reporting framework-level characteristics used in layout, inheritance, and so on



■ Caution Because values for dependency properties can be set in several places, a set of rules define the

precedence of these values and any default value specified in property metadata. These rules are beyond the

scope of this recipe; for more information, you can look at the subject of dependency property value precedence at

http://msdn.microsoft.com/en-us/library/ms743230(VS.100).aspx.



In addition to specifying a default value, property-changed callbacks, and coercion callbacks, the

System.Windows.FrameworkPropertyMetadata object allows you to specify various options given by the

System.Windows.FrameworkPropertyMetadataOptions enumeration. You can use as many of these options

as required, combining them as flags. Table 17-1 details the values defined in the

FrameworkPropertyMetadataOptions enumeration.



791



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

16-14. Create Custom LINQ Extension Methods

Tải bản đầy đủ ngay(0 tr)

×