I want to execute a javascript function on response postback.
I know window.onload=function(){...}, it's init the page,
but I want to reset the page control properties by javascript after the postback, not directly from server.
I have a btnOK, I add the following snippet under btnOK_Click(sender, e);
ScriptManager.RegisterStartupScript(updPanel, GetType(string), "funName", "Alert('hello word!');", True)
It will create a javascript snippet in html on response back. and execute it. on page refresh, it will alert hello word.
2010年12月29日星期三
2010年12月14日星期二
Extension Methods (C# Programming Guide)
Extension Methods (C# Programming Guide)
The following example shows how to call the standard query operator OrderBy method on an array of integers. The expression in parentheses is a lambda expression. Many standard query operators take lambda expressions as parameters, but this is not a requirement for extension methods.
=============================================================
class ExtensionMethods2
{
static void Main()
{
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g);
foreach (var i in result)
{
System.Console.Write(i + " ");
}
}
}
//Output: 10 15 21 26 39 45
=============================================================
Extension methods are defined as static methods but are called by using instance method syntax.
Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier.
Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive.
The following example shows an extension method defined for the System.String class. Note that it is defined inside a non-nested, non-generic static class:
=============================================================
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
The WordCount extension method can be brought into scope with this using directive:
And it can be called from an application by using this syntax:
=============================================================
string s = "Hello Extension Methods";
int i = s.WordCount();
The following example implements an extension method named WordCount in the MyExtensions.StringExtension class
=============================================================
using System.Linq;
using System.Text;
using System;
namespace CustomExtensions
{
//Extension methods must be defined in a static class
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static int WordCount(this String str)
{
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
namespace Extension_Methods_Simple
{
//Import the extension method namespace.
using CustomExtensions;
class Program
{
static void Main(string[] args)
{
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine("Word count of s is {0}", i);
}
}
}
ref: http://msdn.microsoft.com/en-us/library/bb311042.aspx
The following example shows how to call the standard query operator OrderBy method on an array of integers. The expression in parentheses is a lambda expression. Many standard query operators take lambda expressions as parameters, but this is not a requirement for extension methods.
=============================================================
class ExtensionMethods2
{
static void Main()
{
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g);
foreach (var i in result)
{
System.Console.Write(i + " ");
}
}
}
//Output: 10 15 21 26 39 45
=============================================================
Extension methods are defined as static methods but are called by using instance method syntax.
Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier.
Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive.
The following example shows an extension method defined for the System.String class. Note that it is defined inside a non-nested, non-generic static class:
=============================================================
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
The WordCount extension method can be brought into scope with this using directive:
And it can be called from an application by using this syntax:
=============================================================
string s = "Hello Extension Methods";
int i = s.WordCount();
The following example implements an extension method named WordCount in the MyExtensions.StringExtension class
=============================================================
using System.Linq;
using System.Text;
using System;
namespace CustomExtensions
{
//Extension methods must be defined in a static class
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static int WordCount(this String str)
{
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
namespace Extension_Methods_Simple
{
//Import the extension method namespace.
using CustomExtensions;
class Program
{
static void Main(string[] args)
{
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine("Word count of s is {0}", i);
}
}
}
ref: http://msdn.microsoft.com/en-us/library/bb311042.aspx
Filtering with DataView (LINQ to DataSet)
Creating DataView from a Query with Filtering Information
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Int16)("OrderQty") > 2 And _
order.Field(Of Int16)("OrderQty") < 6 _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
The following example creates a DataView from a query for orders placed after June 6, 2001:
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 6, 1) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
The following example uses the SoundEx algorithm to find contacts whose last name is similar to "Zhu". The SoundEx algorithm is implemented in the SoundEx method.
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim soundExCode As String = SoundEx("Zhu")
Dim query = _
From contact In contacts.AsEnumerable() _
Where SoundEx(contact.Field(Of String)("LastName")) = soundExCode _
Select contact
=====================================================
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Using the RowFilter Property
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName") = "Hernandez" _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
view.RowFilter = "LastName='Zhu'"
After a DataView has been created from a DataTable or LINQ to DataSet query, you can use the RowFilter property to specify subsets of rows based on their column values. The string-based and expression-based filters are mutually exclusive. Setting the RowFilter property will clear the filter expression inferred from the LINQ to DataSet query, and the filter expression cannot be reset.
The filter on a DataView can be cleared after filtering has been set using the RowFilter property. The filter on a DataView can be cleared in two different ways:
■Set the RowFilter property to null.
■Set the RowFilter property to an empty string.
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 11, 20) _
And order.Field(Of Decimal)("TotalDue") < New Decimal(60.0) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
view.RowFilter = Nothing
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
' Clear the row filter.
view.RowFilter = ""
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Int16)("OrderQty") > 2 And _
order.Field(Of Int16)("OrderQty") < 6 _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
The following example creates a DataView from a query for orders placed after June 6, 2001:
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 6, 1) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
The following example uses the SoundEx algorithm to find contacts whose last name is similar to "Zhu". The SoundEx algorithm is implemented in the SoundEx method.
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim soundExCode As String = SoundEx("Zhu")
Dim query = _
From contact In contacts.AsEnumerable() _
Where SoundEx(contact.Field(Of String)("LastName")) = soundExCode _
Select contact
=====================================================
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Using the RowFilter Property
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName") = "Hernandez" _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
view.RowFilter = "LastName='Zhu'"
After a DataView has been created from a DataTable or LINQ to DataSet query, you can use the RowFilter property to specify subsets of rows based on their column values. The string-based and expression-based filters are mutually exclusive. Setting the RowFilter property will clear the filter expression inferred from the LINQ to DataSet query, and the filter expression cannot be reset.
The filter on a DataView can be cleared after filtering has been set using the RowFilter property. The filter on a DataView can be cleared in two different ways:
■Set the RowFilter property to null.
■Set the RowFilter property to an empty string.
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 11, 20) _
And order.Field(Of Decimal)("TotalDue") < New Decimal(60.0) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
view.RowFilter = Nothing
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
' Clear the row filter.
view.RowFilter = ""
LINQ Query Syntax versus Method Syntax (C#)
At compile time, query expressions are translated to something that the CLR does understand: method calls.
These methods are called the standard query operators, and they have names such as Where, Select, GroupBy, Join, Max, Average, and so on. You can call them directly by using method syntax instead of query syntax.
The following example shows a simple query expression and the semantically equivalent query written as a method-based query.
class QueryVMethodSyntax
{
static void Main()
{
int[] numbers = { 5, 10, 8, 3, 6, 12};
//Query syntax:
IEnumerable<int> numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;
//Method syntax:
IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
foreach (int i in numQuery1)
{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}
// Keep the console open in debug mode.
Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/*
Output:
6 8 10 12
6 8 10 12
*/
The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: IEnumerable<T>.
If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. These are all the standard query operators.
Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. The standard query operators are implemented as a new kind of method called extension methods. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).
These methods are called the standard query operators, and they have names such as Where, Select, GroupBy, Join, Max, Average, and so on. You can call them directly by using method syntax instead of query syntax.
The following example shows a simple query expression and the semantically equivalent query written as a method-based query.
class QueryVMethodSyntax
{
static void Main()
{
int[] numbers = { 5, 10, 8, 3, 6, 12};
//Query syntax:
IEnumerable<int> numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;
//Method syntax:
IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
foreach (int i in numQuery1)
{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}
// Keep the console open in debug mode.
Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/*
Output:
6 8 10 12
6 8 10 12
*/
The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: IEnumerable<T>.
If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. These are all the standard query operators.
Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. The standard query operators are implemented as a new kind of method called extension methods. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).
Queries in LINQ to DataSet
A query is an expression that retrieves data from a data source. Queries are usually expressed in a specialized query language, such as SQL for relational databases and XQuery for XML. Therefore, developers have had to learn a new query language for each type of data source or data format that they query. Language-Integrated Query (LINQ) offers a simpler, consistent model for working with data across various kinds of data sources and formats. In a LINQ query, you always work with programming objects.
A LINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.
In LINQ, a query is stored in a variable. If the query is designed to return a sequence of values, the query variable itself must be a enumerable type. This query variable takes no action and returns no data; it only stores the query information. After you create a query you must execute that query to retrieve any data.
In contrast to deferred queries, which return a sequence of values, queries that return a singleton value are executed immediately. Some examples of singleton queries are Count, Max, Average, and First. These execute immediately because the query results are required to calculate the singleton result. For example, in order to find the average of the query results the query must be executed so that the averaging function has input data to work with. You can also use the ToList(Of TSource) or ToArray(Of TSource) methods on a query to force immediate execution of a query that does not produce a singleton value. These techniques to force immediate execution can be useful when you want to cache the results of a query. For more information about deferred and immediate query execution, see Getting Started with LINQ.
LINQ to DataSet queries can be formulated in two different syntaxes: query expression syntax and method-based query syntax.
==========================================================
Query Expression Syntax
By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code.
Query expression syntax is new in C# 3.0 and Visual Basic 2008.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
Console.WriteLine(p.Field<string>("Name"));
}
==========================================================
Method-Based Query Syntax
The method-based query syntax is a sequence of direct method calls to LINQ operator methods,
passing lambda expressions as the parameters
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
var query = products.AsEnumerable().
Select(product => new
{
ProductName = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
Price = product.Field<decimal>("ListPrice")
});
Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
==========================================================
Composing Queries
As mentioned earlier in this topic, the query variable itself only stores the query commands when the query is designed to return a sequence of values. If the query does not contain a method that will cause immediate execution, the actual execution of the query is deferred until you iterate over the query variable in a foreach or For Each loop. Deferred execution enables multiple queries to be combined or a query to be extended. When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. In the following example, the first query returns all the products. The second query extends the first by using Where to return all the products of size "L":
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> productsQuery =
from product in products.AsEnumerable()
select product;
IEnumerable<DataRow> largeProducts =
productsQuery.Where(p => p.Field<string>("Size") == "L");
Console.WriteLine("Products of size 'L':");
foreach (DataRow product in largeProducts)
{
Console.WriteLine(product.Field<string>("Name"));
}
After a query has been executed, no additional queries can be composed, and all subsequent queries will use the in-memory LINQ operators. Query execution will occur when you iterate over the query variable in a foreach or For Each statement, or by a call to one of the LINQ conversion operators that cause immediate execution.
These operators include the following: ToList<TSource>, ToArray<TSource>, ToLookup, and ToDictionary.
In the following example, the first query returns all the products ordered by list price. The ToArray<TSource> method is used to force immediate query execution:
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
orderby product.Field<Decimal>("ListPrice") descending
select product;
// Force immediate execution of the query.
IEnumerable<DataRow> productsArray = query.ToArray();
Console.WriteLine("Every price from highest to lowest:");
foreach (DataRow prod in productsArray)
{
Console.WriteLine(prod.Field<Decimal>("ListPrice"));
}
ref: http://msdn.microsoft.com/en-us/library/bb397947.aspx
A LINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.
In LINQ, a query is stored in a variable. If the query is designed to return a sequence of values, the query variable itself must be a enumerable type. This query variable takes no action and returns no data; it only stores the query information. After you create a query you must execute that query to retrieve any data.
In contrast to deferred queries, which return a sequence of values, queries that return a singleton value are executed immediately. Some examples of singleton queries are Count, Max, Average, and First. These execute immediately because the query results are required to calculate the singleton result. For example, in order to find the average of the query results the query must be executed so that the averaging function has input data to work with. You can also use the ToList(Of TSource) or ToArray(Of TSource) methods on a query to force immediate execution of a query that does not produce a singleton value. These techniques to force immediate execution can be useful when you want to cache the results of a query. For more information about deferred and immediate query execution, see Getting Started with LINQ.
LINQ to DataSet queries can be formulated in two different syntaxes: query expression syntax and method-based query syntax.
==========================================================
Query Expression Syntax
By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code.
Query expression syntax is new in C# 3.0 and Visual Basic 2008.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
Console.WriteLine(p.Field<string>("Name"));
}
==========================================================
Method-Based Query Syntax
The method-based query syntax is a sequence of direct method calls to LINQ operator methods,
passing lambda expressions as the parameters
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
var query = products.AsEnumerable().
Select(product => new
{
ProductName = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
Price = product.Field<decimal>("ListPrice")
});
Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
==========================================================
Composing Queries
As mentioned earlier in this topic, the query variable itself only stores the query commands when the query is designed to return a sequence of values. If the query does not contain a method that will cause immediate execution, the actual execution of the query is deferred until you iterate over the query variable in a foreach or For Each loop. Deferred execution enables multiple queries to be combined or a query to be extended. When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. In the following example, the first query returns all the products. The second query extends the first by using Where to return all the products of size "L":
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> productsQuery =
from product in products.AsEnumerable()
select product;
IEnumerable<DataRow> largeProducts =
productsQuery.Where(p => p.Field<string>("Size") == "L");
Console.WriteLine("Products of size 'L':");
foreach (DataRow product in largeProducts)
{
Console.WriteLine(product.Field<string>("Name"));
}
After a query has been executed, no additional queries can be composed, and all subsequent queries will use the in-memory LINQ operators. Query execution will occur when you iterate over the query variable in a foreach or For Each statement, or by a call to one of the LINQ conversion operators that cause immediate execution.
These operators include the following: ToList<TSource>, ToArray<TSource>, ToLookup, and ToDictionary.
In the following example, the first query returns all the products ordered by list price. The ToArray<TSource> method is used to force immediate query execution:
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
orderby product.Field<Decimal>("ListPrice") descending
select product;
// Force immediate execution of the query.
IEnumerable<DataRow> productsArray = query.ToArray();
Console.WriteLine("Every price from highest to lowest:");
foreach (DataRow prod in productsArray)
{
Console.WriteLine(prod.Field<Decimal>("ListPrice"));
}
ref: http://msdn.microsoft.com/en-us/library/bb397947.aspx
Lambda Expressions(operator of " => ") (C# Programming Guide)
A lambda expression is an anonymous function that can contain expressions and statements,
and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
==========================================================
Expression Lambdas
A lambda expression with an expression on the right side is called an expression lambda.
Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual Basic).
An expression lambda returns the result of the expression and takes the following basic form:
(input parameters) => expression
The parentheses are optional only if the lambda has one input parameter;
otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses:
(x, y) => x == y
Sometimes it is difficult or impossible for the compiler to infer the input types. When this occurs,
you can specify the types explicitly as shown in the following example:
(int x, string s) => s.Length > x
Specify zero input parameters with empty parentheses:
() => SomeMethod()
==========================================================
Statement Lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:
(input parameters) => {statement;}
The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.
delegate void TestDelegate(string s);
…
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");
==========================================================
Lambdas with the Standard Query Operators
Many Standard query operators have an input parameter whose type is one of the Func<T, TResult> family of generic delegates. The Func<T, TResult> delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:
public delegate TResult Func<TArg0, TResult>(TArg0 arg0)
The delegate can be instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter. Func<int, string, bool> defines a delegate with two input parameters, int and string, and a return type of bool. The following Func delegate, when it is invoked, will return true or false to indicate whether the input parameter is equal to 5:
Func<int, bool> myFunc = (x => x == 5);
bool result = myFunc(4); // returns false of course
You can also supply a lambda expression when the argument type is an Expression<Func>, for example in the standard query operators that are defined in System.Linq.Queryable. When you specify an Expression<Func> argument, the lambda will be compiled to an expression tree.
A standard query operator, the Count method, is shown here:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
This example shows how to specify multiple input parameters by enclosing them in parentheses.
The method returns all the elements in the numbers array until a number is encountered
whose value is less than its position. Do not confuse the lambda operator (=>) with the greater than
or equal operator (>=).
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
==========================================================
Type Inference in Lambdas
When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:
customers.Where(c => c.City == "London");
The general rules for lambdas are as follows:
■The lambda must contain the same number of parameters as the delegate type.
■Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.
■The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.
==========================================================
Variable Scope in Lambda Expressions
Lambdas can refer to outer variables that are in scope in the enclosing method or type in which the lambda is defined. Variables that are captured in this manner are stored for use in the lambda expression even if variables would otherwise go out of scope and be garbage collected. An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules:
delegate bool D();
delegate bool D2(int i);
class Test
{
D del;
D2 del2;
public void TestMethod(int input)
{
int j = 0;
// Initialize the delegates with lambda expressions.
// Note access to 2 outer variables.
// del will be invoked within this method.
del = () => { j = 10; return j > input; };
// del2 will be invoked after TestMethod goes out of scope.
del2 = (x) => {return x == j; };
// Demonstrate value of j:
// Output: j = 0
// The delegate has not been invoked yet.
Console.WriteLine("j = {0}", j); // Invoke the delegate.
bool boolResult = del();
// Output: j = 10 b = True
Console.WriteLine("j = {0}. b = {1}", j, boolResult);
}
static void Main()
{
Test test = new Test();
test.TestMethod(5);
// Prove that del2 still has a copy of
// local variable j from TestMethod.
bool result = test.del2(10);
// Output: True
Console.WriteLine(result);
Console.ReadKey();
}
}
The following rules apply to variable scope in lambda expressions:
■A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.
■Variables introduced within a lambda expression are not visible in the outer method.
■A lambda expression cannot directly capture a ref or out parameter from an enclosing method.
■A return statement in a lambda expression does not cause the enclosing method to return.
■A lambda expression cannot contain a goto statement, break statement, or continue statement
whose target is outside the body or in the body of a contained anonymous function.
ref: http://msdn.microsoft.com/en-us/library/bb397687.aspx
and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
==========================================================
Expression Lambdas
A lambda expression with an expression on the right side is called an expression lambda.
Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual Basic).
An expression lambda returns the result of the expression and takes the following basic form:
(input parameters) => expression
The parentheses are optional only if the lambda has one input parameter;
otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses:
(x, y) => x == y
Sometimes it is difficult or impossible for the compiler to infer the input types. When this occurs,
you can specify the types explicitly as shown in the following example:
(int x, string s) => s.Length > x
Specify zero input parameters with empty parentheses:
() => SomeMethod()
==========================================================
Statement Lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:
(input parameters) => {statement;}
The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.
delegate void TestDelegate(string s);
…
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");
==========================================================
Lambdas with the Standard Query Operators
Many Standard query operators have an input parameter whose type is one of the Func<T, TResult> family of generic delegates. The Func<T, TResult> delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:
public delegate TResult Func<TArg0, TResult>(TArg0 arg0)
The delegate can be instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter. Func<int, string, bool> defines a delegate with two input parameters, int and string, and a return type of bool. The following Func delegate, when it is invoked, will return true or false to indicate whether the input parameter is equal to 5:
Func<int, bool> myFunc = (x => x == 5);
bool result = myFunc(4); // returns false of course
You can also supply a lambda expression when the argument type is an Expression<Func>, for example in the standard query operators that are defined in System.Linq.Queryable. When you specify an Expression<Func> argument, the lambda will be compiled to an expression tree.
A standard query operator, the Count method, is shown here:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
This example shows how to specify multiple input parameters by enclosing them in parentheses.
The method returns all the elements in the numbers array until a number is encountered
whose value is less than its position. Do not confuse the lambda operator (=>) with the greater than
or equal operator (>=).
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
==========================================================
Type Inference in Lambdas
When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:
customers.Where(c => c.City == "London");
The general rules for lambdas are as follows:
■The lambda must contain the same number of parameters as the delegate type.
■Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.
■The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.
==========================================================
Variable Scope in Lambda Expressions
Lambdas can refer to outer variables that are in scope in the enclosing method or type in which the lambda is defined. Variables that are captured in this manner are stored for use in the lambda expression even if variables would otherwise go out of scope and be garbage collected. An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules:
delegate bool D();
delegate bool D2(int i);
class Test
{
D del;
D2 del2;
public void TestMethod(int input)
{
int j = 0;
// Initialize the delegates with lambda expressions.
// Note access to 2 outer variables.
// del will be invoked within this method.
del = () => { j = 10; return j > input; };
// del2 will be invoked after TestMethod goes out of scope.
del2 = (x) => {return x == j; };
// Demonstrate value of j:
// Output: j = 0
// The delegate has not been invoked yet.
Console.WriteLine("j = {0}", j); // Invoke the delegate.
bool boolResult = del();
// Output: j = 10 b = True
Console.WriteLine("j = {0}. b = {1}", j, boolResult);
}
static void Main()
{
Test test = new Test();
test.TestMethod(5);
// Prove that del2 still has a copy of
// local variable j from TestMethod.
bool result = test.del2(10);
// Output: True
Console.WriteLine(result);
Console.ReadKey();
}
}
The following rules apply to variable scope in lambda expressions:
■A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.
■Variables introduced within a lambda expression are not visible in the outer method.
■A lambda expression cannot directly capture a ref or out parameter from an enclosing method.
■A return statement in a lambda expression does not cause the enclosing method to return.
■A lambda expression cannot contain a goto statement, break statement, or continue statement
whose target is outside the body or in the body of a contained anonymous function.
ref: http://msdn.microsoft.com/en-us/library/bb397687.aspx
2010年12月10日星期五
2010年12月9日星期四
GridView Databinding注意事項
GridViewのデータバインディングについて、MSDNにはいろいろな例がありますが、
EIDTモード場合のバインディングは足りないと思います。
GridViewはDatatableにバインディングした後、Editモードにするのはどうすればいいか、
はっきりしていないです。
実際にはGridViewのEditIndexを設定すればOKです。
即ち、以下のソースで説明します。
Protected Sub Grid_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) _
Handles grd.RowEditing
’編集開始イベントの中で、新たな編集先行番を設定する必要です。
grd.EditIndex= e.NewEditIndex
'設定完了後、再びGridにDataSourceのバインディングが必要です。
grd.DataBind()
End Sub
なお、編集キャンセルしたい場合、GridView.EditIndex=-1にリセットが必要です。
キャンセルボタンに関連することも可能です。
Protected Sub Grid_RowCancelingEdit(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs) _
Handles grd.RowCancelingEdit
grd.EditIndex= -1
grd.DataBind()
End Sub
===============
同じく、GridViewの行選択が変わりたい場合、GridView.SelectedIndexの指定が必要です。
以下例:
Protected Sub Grid_SelectedIndexChanging(ByVal sender As Object, ByVal e As GridViewSelectEventArgs) Handles grd.SelectedIndexChanging
grd.SelectedIndex = e.NewSelectedIndex
grd.DataBind()
End Sub
===============
同じくGridViewの頁が変わりたい場合、GridView.PageIndexの指定が必要です。
以下例:
Protected Sub Grid_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) _
Handles grd.PageIndexChanging
if grd.PageIndex <> e.NewPageIndex then
grd.PageIndex = e.NewPageIndex
End If
grd.DataBind()
End Sub
以上の例は皆変更しようとすると、対応Indexの設定が必要で、その後またDataBind()の再バインディングが必要です。しないと、データが表示しないです。
grdのDataSourceはGridViewのEnableViewState=trueの場合(ディフォルトはtrue)、ViewStateの保存されます、再DataSourceの指定は不要です、逆に指定したら、新たなDataSourceとして扱うことになります。
EIDTモード場合のバインディングは足りないと思います。
GridViewはDatatableにバインディングした後、Editモードにするのはどうすればいいか、
はっきりしていないです。
実際にはGridViewのEditIndexを設定すればOKです。
即ち、以下のソースで説明します。
Protected Sub Grid_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) _
Handles grd.RowEditing
’編集開始イベントの中で、新たな編集先行番を設定する必要です。
grd.EditIndex= e.NewEditIndex
'設定完了後、再びGridにDataSourceのバインディングが必要です。
grd.DataBind()
End Sub
なお、編集キャンセルしたい場合、GridView.EditIndex=-1にリセットが必要です。
キャンセルボタンに関連することも可能です。
Protected Sub Grid_RowCancelingEdit(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs) _
Handles grd.RowCancelingEdit
grd.EditIndex= -1
grd.DataBind()
End Sub
===============
同じく、GridViewの行選択が変わりたい場合、GridView.SelectedIndexの指定が必要です。
以下例:
Protected Sub Grid_SelectedIndexChanging(ByVal sender As Object, ByVal e As GridViewSelectEventArgs) Handles grd.SelectedIndexChanging
grd.SelectedIndex = e.NewSelectedIndex
grd.DataBind()
End Sub
===============
同じくGridViewの頁が変わりたい場合、GridView.PageIndexの指定が必要です。
以下例:
Protected Sub Grid_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) _
Handles grd.PageIndexChanging
if grd.PageIndex <> e.NewPageIndex then
grd.PageIndex = e.NewPageIndex
End If
grd.DataBind()
End Sub
以上の例は皆変更しようとすると、対応Indexの設定が必要で、その後またDataBind()の再バインディングが必要です。しないと、データが表示しないです。
grdのDataSourceはGridViewのEnableViewState=trueの場合(ディフォルトはtrue)、ViewStateの保存されます、再DataSourceの指定は不要です、逆に指定したら、新たなDataSourceとして扱うことになります。
データ バインディング構文
データ バインディング式は <%# デリミタと %> デリミタの間に記述され、Eval 関数と Bind 関数を使用します。Eval 関数は、一方向 (読み取り専用) バインディングを定義するために使用します。Bind 関数は、双方向 (更新可能) バインディングに使用します。Eval メソッドと Bind メソッドを呼び出してデータ バインディング式でデータ バインディングを実行することに加えて、<%# デリミタと %> デリミタの間でパブリックにスコープされた任意のコードを呼び出して実行し、ページの処理中に値を返すことができます。
データ バインディング式は、コントロールの DataBind メソッドまたは Page クラスが呼び出されたときに解決されます。GridView、DetailsView、FormView などのコントロールでは、データ バインディング式はコントロールの PreRender イベントの中で自動的に解決されるので、DataBind メソッドを明示的に呼び出す必要はありません。
ItemTemplate の FormView コントロールと共にデータ バインディング式を使用するコード例を次に示します。
Eval メソッドの使用
Eval メソッドは、GridView、DetailsView、FormView などのデータ バインド コントロールのテンプレートの遅延バインディング データ式を評価します。Eval メソッドは、名前付けコンテナの現在のデータ項目を参照する DataBinder オブジェクトの Eval メソッドを実行時に呼び出します。名前付けコンテナは、GridView コントロールの行などのように、一般にレコード全体を含むデータ バインド コントロールの最小単位です。したがって、Eval メソッドは、データ バインド コントロールのテンプレート内のバインディングにのみ使用できます。
Eval メソッドはデータ フィールドの名前を受け取り、データ ソースの現在のレコードからそのフィールドの値を含む文字列を返します。2 番目のパラメータを指定して、返される文字列の形式を指定することもできます (省略可能)。文字列の書式指定パラメータは、String クラスの Format メソッドに対して定義された構文を使用します。
<asp:FormView ID="FormView1"
DataSourceID="SqlDataSource1"
DataKeyNames="ProductID"
RunAt="server">
<ItemTemplate>
<table>
<tr><td align="right"><b>Product ID:</b></td> <td><%# Eval("ProductID") %></td></tr>
<tr><td align="right"><b>Product Name:</b></td> <td><%# Eval("ProductName") %></td></tr>
<tr><td align="right"><b>Category ID:</b></td> <td><%# Eval("CategoryID") %></td></tr>
<tr><td align="right"><b>Quantity Per Unit:</b></td><td><%# Eval("QuantityPerUnit") %></td></tr>
<tr><td align="right"><b>Unit Price:</b></td> <td><%# Eval("UnitPrice") %></td></tr>
</table>
</ItemTemplate>
</asp:FormView>
Bind メソッドの使用
Bind メソッドは、Eval メソッドに部分的に似ていますが、重要な違いがあります。Eval メソッドと同様に、Bind メソッドを使用してもデータ バインド フィールドの値を取得できますが、Bind メソッドはデータを変更できる場合にも使用します。
ASP.NET では、GridView、DetailsView、FormView などのデータ バインド コントロールは、データ ソース コントロールの更新、削除、および挿入操作を自動的に使用します。たとえば、データ ソース コントロールに対して SQL の Select、Insert、Delete、および Update ステートメントを定義している場合、GridView、DetailsView、または FormView コントロールのテンプレートで Bind を使用すると、そのコントロールで、テンプレートの子コントロールから値を抽出してデータ ソース コントロールに渡すことができます。次に、データ ソース コントロールは、データベースに対して適切なコマンドを実行します。そのために、データ バインド コントロールの EditItemTemplate または InsertItemTemplate の内部では Bind 関数が使用されます。
Bind メソッドは、編集モードの GridView 行によってレンダリングされた TextBox コントロールなどの入力コントロールで一般的に使用されます。データ バインド コントロールは、自身のレンダリング処理の一部としてこのような入力コントロールを作成する場合、入力値を抽出できます。
Bind メソッドは、次の例に示すように、データ フィールドの名前を受け取ってバインド プロパティに関連付けます。
セキュリティに関するメモ :
この例には、ユーザー入力を受け付けるテキスト ボックスがあるため、セキュリティ上の脅威になる可能性があります。既定では、ASP.NET Web ページは、ユーザー入力にスクリプトまたは HTML 要素が含まれていないことを検証します。詳細については、「スクリプトによる攻略の概要」を参照してください。
コピー<EditItemTemplate>
<table>
<tr>
<td align=right>
<b>Employee ID:</b>
</td>
<td>
<%# Eval("EmployeeID") %>
</td>
</tr>
<tr>
<td align=right>
<b>First Name:</b>
</td>
<td>
<asp:TextBox ID="EditFirstNameTextBox" RunAt="Server"
Text='<%# Bind("FirstName") %>' />
</td>
</tr>
<tr>
<td align=right>
<b>Last Name:</b>
</td>
<td>
<asp:TextBox ID="EditLastNameTextBox" RunAt="Server"
Text='<%# Bind("LastName") %>' />
</td>
</tr>
<tr>
<td colspan="2">
<asp:LinkButton ID="UpdateButton" RunAt="server"
Text="Update" CommandName="Update" />
<asp:LinkButton ID="CancelUpdateButton" RunAt="server"
Text="Cancel" CommandName="Cancel" />
</td>
</tr>
</table>
</EditItemTemplate>
行の Update ボタンがクリックされると、Bind 構文を使用してバインドされた各コントロール プロパティの値が抽出され、更新操作のためにデータ ソース コントロールに渡されます。
DataBind メソッドの明示的な呼び出し
GridView、FormView、DetailsView などのコントロールは、DataSourceID プロパティを使用してデータ ソース コントロールにバインドされるときに DataBind メソッドを暗黙的に呼び出してバインディングを実行します。ただし、明示的に DataBind メソッドを呼び出す必要がある場合もあります。
そのような状況の 1 つは、DataSourceID プロパティの代わりに DataSource プロパティを使用してコントロールをデータ ソース コントロールにバインドした場合です。その場合は、明示的に DataBind メソッドを呼び出してデータ バインディングを実行し、データ バインディング式を解決する必要があります。
もう 1 つの状況は、データ バインド コントロールのデータを手動で更新する必要がある場合です。同じデータベースから情報を表示する 2 つのコントロールを含むページがあるとします。おそらく個別のビューを使用しています。この場合、データ表示の同期を維持するために明示的にデータにコントロールを再バインドする必要があります。たとえば、製品の一覧を表示する GridView コントロールおよびユーザーが製品を個々に編集するための DetailsView コントロールがあるとします。GridView コントロールと DetailsView コントロールは同じソースからデータを表示しますが、異なるクエリを使用してデータを取得しているので、別のデータ ソース コントロールにバインドされています。ユーザーが DetailsView コントロールを使用してレコードを更新すると、関連付けられているデータ ソース コントロールによって更新処理が実行されます。ただし、GridView コントロールは、別のデータ ソース コントロールにバインドされているので、ページが更新されるまで古いレコードの値が表示されます。そこで、DetailsView コントロールがデータを更新した後に、DataBind メソッドを呼び出します。これによって、<%# デリミタと %> デリミタの間のすべてのデータ バインディング式およびパブリックにスコープされたコードが再実行され、GridView コントロールのビューが更新されます。その結果、GridView コントロールに DetailsView コントロールによる更新内容が反映されます。
ルックアップ テーブルへのバインディングの使用
データ バインド コントロールは、ユーザーが DropDownList コントロールまたは他のリスト コントロールを使用し、ルックアップ テーブルから選択して値を更新または挿入できるようにする場合によく使用されます。この場合、ルックアップ コントロールは、可能な値の一覧を返す個別のデータ ソースにバインドされます。またルックアップ コントロールの選択した値は、親データ バインドの行のフィールドにバインドされます。
この機能は次の手順で追加できます。まず、ルックアップ コントロールについて、リスト コントロール (DropDownList コントロールまたは ListBox コントロール) をデータ バインド コントロール (GridView、DetailsView、FormView などの各コントロール) のテンプレートに追加します。ルックアップ コントロールの SelectedValue プロパティは、コンテナ コントロールのデータ ソースにある関連フィールドにバインドします。次に、ルックアップ コントロールの DataSourceID プロパティを、ルックアップ値を取得するデータ ソース コントロールに設定します。ルックアップ コントロールの DataTextField プロパティは、表示する値を含むルックアップ テーブルのフィールドに設定します。また、適用できる場合、DataValueField プロパティは、ルックアップ値の固有な識別子を含むルックアップ テーブルのフィールドに設定します。
次のコード例は、FormView コントロールの InsertItemTemplate テンプレートに含まれる DropDownList コントロールです (これは、DetailsView コントロールの Fields プロパティまたは GridView コントロールの Columns プロパティに含まれる、TemplateField の InsertItemTemplate テンプレートの可能性もあります)。DropDownList コントロールの SelectedValue プロパティは、Bind メソッドを使用して、FormView コントロールの現在の行の CategoryID フィールドに双方向にバインディングします。DataSourceID コントロールの DropDownList プロパティは、可能なカテゴリ名と ID の一覧を取得する個別のデータ ソース コントロールに設定されます。DropDownList コントロールの DataTextField プロパティは、可能なカテゴリ名が表示されるように、ルックアップ データ ソースの CategoryName フィールドに設定されます。DropDownList コントロールの DataValueField プロパティは、関連するカテゴリ名のルックアップ データ ソースの CategoryID フィールドに設定されます。ユーザーがリストからカテゴリ名を選択すると、DropDownList コントロールの SelectedValue プロパティは、選択したカテゴリ名のカテゴリ ID に設定されます。
VBC#C++F#JScript
コピー<tr>
<td align="right"><b>Category:</b></td>
<td><asp:DropDownList ID="InsertCategoryDropDownList"
SelectedValue='<%# Bind("CategoryID") %>'
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName"
DataValueField="CategoryID"
RunAt="Server" />
</td>
</tr>
同じリスト コントロールを編集項目のテンプレートにも使用できます。
データ バインディング式は、コントロールの DataBind メソッドまたは Page クラスが呼び出されたときに解決されます。GridView、DetailsView、FormView などのコントロールでは、データ バインディング式はコントロールの PreRender イベントの中で自動的に解決されるので、DataBind メソッドを明示的に呼び出す必要はありません。
ItemTemplate の FormView コントロールと共にデータ バインディング式を使用するコード例を次に示します。
Eval メソッドの使用
Eval メソッドは、GridView、DetailsView、FormView などのデータ バインド コントロールのテンプレートの遅延バインディング データ式を評価します。Eval メソッドは、名前付けコンテナの現在のデータ項目を参照する DataBinder オブジェクトの Eval メソッドを実行時に呼び出します。名前付けコンテナは、GridView コントロールの行などのように、一般にレコード全体を含むデータ バインド コントロールの最小単位です。したがって、Eval メソッドは、データ バインド コントロールのテンプレート内のバインディングにのみ使用できます。
Eval メソッドはデータ フィールドの名前を受け取り、データ ソースの現在のレコードからそのフィールドの値を含む文字列を返します。2 番目のパラメータを指定して、返される文字列の形式を指定することもできます (省略可能)。文字列の書式指定パラメータは、String クラスの Format メソッドに対して定義された構文を使用します。
<asp:FormView ID="FormView1"
DataSourceID="SqlDataSource1"
DataKeyNames="ProductID"
RunAt="server">
<ItemTemplate>
<table>
<tr><td align="right"><b>Product ID:</b></td> <td><%# Eval("ProductID") %></td></tr>
<tr><td align="right"><b>Product Name:</b></td> <td><%# Eval("ProductName") %></td></tr>
<tr><td align="right"><b>Category ID:</b></td> <td><%# Eval("CategoryID") %></td></tr>
<tr><td align="right"><b>Quantity Per Unit:</b></td><td><%# Eval("QuantityPerUnit") %></td></tr>
<tr><td align="right"><b>Unit Price:</b></td> <td><%# Eval("UnitPrice") %></td></tr>
</table>
</ItemTemplate>
</asp:FormView>
Bind メソッドの使用
Bind メソッドは、Eval メソッドに部分的に似ていますが、重要な違いがあります。Eval メソッドと同様に、Bind メソッドを使用してもデータ バインド フィールドの値を取得できますが、Bind メソッドはデータを変更できる場合にも使用します。
ASP.NET では、GridView、DetailsView、FormView などのデータ バインド コントロールは、データ ソース コントロールの更新、削除、および挿入操作を自動的に使用します。たとえば、データ ソース コントロールに対して SQL の Select、Insert、Delete、および Update ステートメントを定義している場合、GridView、DetailsView、または FormView コントロールのテンプレートで Bind を使用すると、そのコントロールで、テンプレートの子コントロールから値を抽出してデータ ソース コントロールに渡すことができます。次に、データ ソース コントロールは、データベースに対して適切なコマンドを実行します。そのために、データ バインド コントロールの EditItemTemplate または InsertItemTemplate の内部では Bind 関数が使用されます。
Bind メソッドは、編集モードの GridView 行によってレンダリングされた TextBox コントロールなどの入力コントロールで一般的に使用されます。データ バインド コントロールは、自身のレンダリング処理の一部としてこのような入力コントロールを作成する場合、入力値を抽出できます。
Bind メソッドは、次の例に示すように、データ フィールドの名前を受け取ってバインド プロパティに関連付けます。
セキュリティに関するメモ :
この例には、ユーザー入力を受け付けるテキスト ボックスがあるため、セキュリティ上の脅威になる可能性があります。既定では、ASP.NET Web ページは、ユーザー入力にスクリプトまたは HTML 要素が含まれていないことを検証します。詳細については、「スクリプトによる攻略の概要」を参照してください。
コピー<EditItemTemplate>
<table>
<tr>
<td align=right>
<b>Employee ID:</b>
</td>
<td>
<%# Eval("EmployeeID") %>
</td>
</tr>
<tr>
<td align=right>
<b>First Name:</b>
</td>
<td>
<asp:TextBox ID="EditFirstNameTextBox" RunAt="Server"
Text='<%# Bind("FirstName") %>' />
</td>
</tr>
<tr>
<td align=right>
<b>Last Name:</b>
</td>
<td>
<asp:TextBox ID="EditLastNameTextBox" RunAt="Server"
Text='<%# Bind("LastName") %>' />
</td>
</tr>
<tr>
<td colspan="2">
<asp:LinkButton ID="UpdateButton" RunAt="server"
Text="Update" CommandName="Update" />
<asp:LinkButton ID="CancelUpdateButton" RunAt="server"
Text="Cancel" CommandName="Cancel" />
</td>
</tr>
</table>
</EditItemTemplate>
行の Update ボタンがクリックされると、Bind 構文を使用してバインドされた各コントロール プロパティの値が抽出され、更新操作のためにデータ ソース コントロールに渡されます。
DataBind メソッドの明示的な呼び出し
GridView、FormView、DetailsView などのコントロールは、DataSourceID プロパティを使用してデータ ソース コントロールにバインドされるときに DataBind メソッドを暗黙的に呼び出してバインディングを実行します。ただし、明示的に DataBind メソッドを呼び出す必要がある場合もあります。
そのような状況の 1 つは、DataSourceID プロパティの代わりに DataSource プロパティを使用してコントロールをデータ ソース コントロールにバインドした場合です。その場合は、明示的に DataBind メソッドを呼び出してデータ バインディングを実行し、データ バインディング式を解決する必要があります。
もう 1 つの状況は、データ バインド コントロールのデータを手動で更新する必要がある場合です。同じデータベースから情報を表示する 2 つのコントロールを含むページがあるとします。おそらく個別のビューを使用しています。この場合、データ表示の同期を維持するために明示的にデータにコントロールを再バインドする必要があります。たとえば、製品の一覧を表示する GridView コントロールおよびユーザーが製品を個々に編集するための DetailsView コントロールがあるとします。GridView コントロールと DetailsView コントロールは同じソースからデータを表示しますが、異なるクエリを使用してデータを取得しているので、別のデータ ソース コントロールにバインドされています。ユーザーが DetailsView コントロールを使用してレコードを更新すると、関連付けられているデータ ソース コントロールによって更新処理が実行されます。ただし、GridView コントロールは、別のデータ ソース コントロールにバインドされているので、ページが更新されるまで古いレコードの値が表示されます。そこで、DetailsView コントロールがデータを更新した後に、DataBind メソッドを呼び出します。これによって、<%# デリミタと %> デリミタの間のすべてのデータ バインディング式およびパブリックにスコープされたコードが再実行され、GridView コントロールのビューが更新されます。その結果、GridView コントロールに DetailsView コントロールによる更新内容が反映されます。
ルックアップ テーブルへのバインディングの使用
データ バインド コントロールは、ユーザーが DropDownList コントロールまたは他のリスト コントロールを使用し、ルックアップ テーブルから選択して値を更新または挿入できるようにする場合によく使用されます。この場合、ルックアップ コントロールは、可能な値の一覧を返す個別のデータ ソースにバインドされます。またルックアップ コントロールの選択した値は、親データ バインドの行のフィールドにバインドされます。
この機能は次の手順で追加できます。まず、ルックアップ コントロールについて、リスト コントロール (DropDownList コントロールまたは ListBox コントロール) をデータ バインド コントロール (GridView、DetailsView、FormView などの各コントロール) のテンプレートに追加します。ルックアップ コントロールの SelectedValue プロパティは、コンテナ コントロールのデータ ソースにある関連フィールドにバインドします。次に、ルックアップ コントロールの DataSourceID プロパティを、ルックアップ値を取得するデータ ソース コントロールに設定します。ルックアップ コントロールの DataTextField プロパティは、表示する値を含むルックアップ テーブルのフィールドに設定します。また、適用できる場合、DataValueField プロパティは、ルックアップ値の固有な識別子を含むルックアップ テーブルのフィールドに設定します。
次のコード例は、FormView コントロールの InsertItemTemplate テンプレートに含まれる DropDownList コントロールです (これは、DetailsView コントロールの Fields プロパティまたは GridView コントロールの Columns プロパティに含まれる、TemplateField の InsertItemTemplate テンプレートの可能性もあります)。DropDownList コントロールの SelectedValue プロパティは、Bind メソッドを使用して、FormView コントロールの現在の行の CategoryID フィールドに双方向にバインディングします。DataSourceID コントロールの DropDownList プロパティは、可能なカテゴリ名と ID の一覧を取得する個別のデータ ソース コントロールに設定されます。DropDownList コントロールの DataTextField プロパティは、可能なカテゴリ名が表示されるように、ルックアップ データ ソースの CategoryName フィールドに設定されます。DropDownList コントロールの DataValueField プロパティは、関連するカテゴリ名のルックアップ データ ソースの CategoryID フィールドに設定されます。ユーザーがリストからカテゴリ名を選択すると、DropDownList コントロールの SelectedValue プロパティは、選択したカテゴリ名のカテゴリ ID に設定されます。
VBC#C++F#JScript
コピー<tr>
<td align="right"><b>Category:</b></td>
<td><asp:DropDownList ID="InsertCategoryDropDownList"
SelectedValue='<%# Bind("CategoryID") %>'
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName"
DataValueField="CategoryID"
RunAt="Server" />
</td>
</tr>
同じリスト コントロールを編集項目のテンプレートにも使用できます。
DataSource紹介 ー概略
データ ソース コントロール 説明
ObjectDataSource
ビジネス オブジェクトまたはその他のクラスと共に使用し、中間層オブジェクトに依存する Web アプリケーションを作成してデータを管理します。
詳細については、「ObjectDataSource Web サーバー コントロール」を参照してください。
SqlDataSource
Microsoft SQL Server、OLE DB、ODBC、または Oracle データベースへのアクセスを提供する ADO.NET マネージ データ プロバイダを使用できます。
詳細については、「SqlDataSource Web サーバー コントロール」を参照してください。
AccessDataSource
Microsoft Access データベースで使用できます。
詳細については、「AccessDataSource Web サーバー コントロール」を参照してください。
XmlDataSource
TreeView コントロール、Menu コントロールなどの階層的な ASP.NET サーバー コントロールで特に有効な XML ファイルを使用できます。
詳細については、「XmlDataSource Web サーバー コントロール」を参照してください。
SiteMapDataSource
ASP.NET サイト ナビゲーションで使用します。詳細については、「ASP.NET サイト ナビゲーションの概要」を参照してください。
ObjectDataSource
ビジネス オブジェクトまたはその他のクラスと共に使用し、中間層オブジェクトに依存する Web アプリケーションを作成してデータを管理します。
詳細については、「ObjectDataSource Web サーバー コントロール」を参照してください。
SqlDataSource
Microsoft SQL Server、OLE DB、ODBC、または Oracle データベースへのアクセスを提供する ADO.NET マネージ データ プロバイダを使用できます。
詳細については、「SqlDataSource Web サーバー コントロール」を参照してください。
AccessDataSource
Microsoft Access データベースで使用できます。
詳細については、「AccessDataSource Web サーバー コントロール」を参照してください。
XmlDataSource
TreeView コントロール、Menu コントロールなどの階層的な ASP.NET サーバー コントロールで特に有効な XML ファイルを使用できます。
詳細については、「XmlDataSource Web サーバー コントロール」を参照してください。
SiteMapDataSource
ASP.NET サイト ナビゲーションで使用します。詳細については、「ASP.NET サイト ナビゲーションの概要」を参照してください。
DataSource紹介 - ObjectDataSource
ObjectDataSourceは中間層ビジネス オブジェクトとして扱うのは普通です。
使う前に、対応ビジネスオブジェクトが必要です。
例:
===============
Namespace Samples.DataSources
Public Class TestObjectDataSource
' Select all employees.
Public Function GetTestData(key as string) As DataTable
return new DataTable
End Function
public Function Update(dt as DataTable) as Integer
'更新
return 0
End Function
public Function Delete(dt as DataTable) as Integer
'削除
return 0
End Function
End Class
End Namespace
===============
<html>
<asp:ObjectDataSource
ID="TestObjectDataSource1"
runat="server"
TypeName="Samples.DataSources.TestObjectDataSource"
EnablePaging="true"
SelectCountMethod="SelectCount"
StartRowIndexParameterName="StartRecord"
MaximumRowsParameterName="MaxRecords"
SelectMethod="GetTestData" >
</asp:ObjectDataSource>
<asp:GridView ID="EmployeesGridView"
DataSourceID="TestObjectDataSource1" >
</asp:GridView>
</html>
使う前に、対応ビジネスオブジェクトが必要です。
例:
===============
Namespace Samples.DataSources
Public Class TestObjectDataSource
' Select all employees.
Public Function GetTestData(key as string) As DataTable
return new DataTable
End Function
public Function Update(dt as DataTable) as Integer
'更新
return 0
End Function
public Function Delete(dt as DataTable) as Integer
'削除
return 0
End Function
End Class
End Namespace
===============
<html>
<asp:ObjectDataSource
ID="TestObjectDataSource1"
runat="server"
TypeName="Samples.DataSources.TestObjectDataSource"
EnablePaging="true"
SelectCountMethod="SelectCount"
StartRowIndexParameterName="StartRecord"
MaximumRowsParameterName="MaxRecords"
SelectMethod="GetTestData" >
</asp:ObjectDataSource>
<asp:GridView ID="EmployeesGridView"
DataSourceID="TestObjectDataSource1" >
</asp:GridView>
</html>
2010年12月8日星期三
组织的力量
成大事者必然存在于某个组织,脱离了组织,个人什么都不是。
个人在组织中的位置越高,影响力就越强,个人可以发挥能力就越强。
组织的力量,取决于领导的能力。
领导代表权利,更代表义务。
如何成为领导,首先考虑成为组织的一员,成为组织成员的目的是什么。
健康的组织,像阳光普照每一个角落。
作为一名新人,如何最快速的成为组织中的领头羊,是学习的意识和能力。
个人在组织中的位置越高,影响力就越强,个人可以发挥能力就越强。
组织的力量,取决于领导的能力。
领导代表权利,更代表义务。
如何成为领导,首先考虑成为组织的一员,成为组织成员的目的是什么。
健康的组织,像阳光普照每一个角落。
作为一名新人,如何最快速的成为组织中的领头羊,是学习的意识和能力。
新闻-中国民间发明家发明致穷-读后感
从网上看到的[民间发明家发明致穷]这篇报道, 让我突发奇想,从这篇报道里,
我看到了一个项目。
1 是否能够将专利统一管理,建立市场,公开销售/竞售。
2 如何收集专利,与发明人取得联系并长期合作。
3 如何鉴别专利的真假。
4 如何评价专利的市场价值。
5 如何调节专利提供者与需求者之间的关系。
6 是否能够提供一种先有需求后搞发明的服务模式。
7 是否有启动资金,启动平台,是否有时间。
8 是否能够找到总负责本项目的合适人选,及其他相关角色的人选。
9 如何能让思想不半途而废。
新闻提到了美国日本的发明专利转化率高达80%,中国的不到5%.
说明一个严重的问题是国家的发明专利机构不作为,只负责登记,其他一概不问。
我们是否能够模拟专利组织,处理所有专利组织不作为的部分,
就是评估专利,专利推广等上面提到的问题。
题外话:
金融业: 支付宝虽然不是银行,却做到了银行的本质。
物流业: 已经不再是邮局的天下。
那么还有哪些衙门还有哪些地方不作为,可以为我们小老百姓创造就业机会的呢。
本人联系方式lqwangxg@gmail.com. 对讨论创业感兴趣的,可以做个朋友。
———————————————————————————————————
机会就在每一天。
我看到了一个项目。
1 是否能够将专利统一管理,建立市场,公开销售/竞售。
2 如何收集专利,与发明人取得联系并长期合作。
3 如何鉴别专利的真假。
4 如何评价专利的市场价值。
5 如何调节专利提供者与需求者之间的关系。
6 是否能够提供一种先有需求后搞发明的服务模式。
7 是否有启动资金,启动平台,是否有时间。
8 是否能够找到总负责本项目的合适人选,及其他相关角色的人选。
9 如何能让思想不半途而废。
新闻提到了美国日本的发明专利转化率高达80%,中国的不到5%.
说明一个严重的问题是国家的发明专利机构不作为,只负责登记,其他一概不问。
我们是否能够模拟专利组织,处理所有专利组织不作为的部分,
就是评估专利,专利推广等上面提到的问题。
题外话:
金融业: 支付宝虽然不是银行,却做到了银行的本质。
物流业: 已经不再是邮局的天下。
那么还有哪些衙门还有哪些地方不作为,可以为我们小老百姓创造就业机会的呢。
本人联系方式lqwangxg@gmail.com. 对讨论创业感兴趣的,可以做个朋友。
———————————————————————————————————
机会就在每一天。
2010年12月1日星期三
.net Control継承にToolboxBitmap利用
VS IDE(VS2008等)の Toolboxに既存しているControlを継承して、新たなControlを作る時に、
継承ControlのBitmapはディフォルトの◎で表示されています。
親のBitmapを表示させる方法があります。
以下例のようにToolboxBitmapの属性を使えば簡単にできる:
C#
[ToolboxBitmap(typeof(TextBox))]
public class CurrencyTextBox : TextBox, IScriptControl, IValidator, IIsRequired
{
...
}
=============================================
VB.net
<ToolboxBitmap(GetType(TextBox))> _
Public Class CurrencyTextBox
Inherits TextBox
Implements IScriptControl, IValidator, IIsRequired
...
End Class
継承ControlのBitmapはディフォルトの◎で表示されています。
親のBitmapを表示させる方法があります。
以下例のようにToolboxBitmapの属性を使えば簡単にできる:
C#
[ToolboxBitmap(typeof(TextBox))]
public class CurrencyTextBox : TextBox, IScriptControl, IValidator, IIsRequired
{
...
}
=============================================
VB.net
<ToolboxBitmap(GetType(TextBox))> _
Public Class CurrencyTextBox
Inherits TextBox
Implements IScriptControl, IValidator, IIsRequired
...
End Class
订阅:
博文 (Atom)