Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Apress pro Silverlight 3 in C# phần 4 pdf
Nội dung xem thử
Mô tả chi tiết
CHAPTER 5 ■ ELEMENTS
172
}
}
You then decide to build an AutoCompleteBox that attempts to match the user’s text
with a Product object. In preparation for this step, you fill the AutoComplexBox.ItemsSource
collection with product objects:
Product[] products = new []{
new Product("Peanut Butter Applicator", "C_PBA-01"),
new Product("Pelvic Strengthener", "C_PVS-309"), ...};
acbProduct.ItemsSource = products;
If you take no further steps, the AutoCompleteBox will use its standard behavior. As
the user types, it will call ToString() on each Product object. It will then use that text to perform
its suggestion filtering. Because the Product class overrides the ToString() method to return the
product name, the AutoCompleteBox will attempt to match the user’s text with a product
name, which is perfectly reasonable.
However, if you perform custom filtering you can get a bit more sophisticated. For
example, you can check if the user’s text matches the ProductName property or the
ProductCode property and deem the Product object as a match either way. Here’s an example
of the custom filtering logic that does the trick:
public bool ProductItemFilter(string text, object item)
{
Product product = (Product)item;
// Call it a match if the typed-in text appears in the product code
// or at the beginning of the product name.
return ((product.ProductName.StartsWith(text)) ||
(product.ProductCode.Contains(text)));
}
You simply need to connect this method to your AutoComplexBox when it’s first
initialized:
acbProduct.ItemFilter = ProductItemFilter;
Now if the user types the text PBA, it matches the product code C_PBA-01 and see the
matching item Peanut Butter Applicator in the list of suggestions, as shown in Figure 5-15.
CHAPTER 5 ■ ELEMENTS
173
Figure 5-15. A custom search that matches product codes
Dynamic Item Lists
So far, you’ve used the ItemsSource property to fill the AutoCompleteBox with a collection of
suggestions. For this to work, you must have the complete list and it must be a manageable size.
If you need to pull the information from somewhere else or the list is large enough that it isn’t
practical to load the whole thing at once, you’ll need to take a different approach to filling the
AutoCompleteBox. Instead of setting the ItemsSource property when the page is first created,
you’ll need to set it in real time, as the user types.
To do so, set the FilterMode property to None, and handle the Populating event. The
Populating event fires whenever the AutoCompleteBox is ready to search for results. By default,
this happens every time the user presses a key and changes the current text entry. You can
make the AutoCompleteBox somewhat more relaxed using the MinimumPrefixLength and
MinimumPopupDelay properties that are discussed at the end of this section.
<input:AutoCompleteBox x:Name="acbProducts" FilterMode="None"
Populating="acbProducts_Populating" ></input:AutoCompleteBox>
When the Populating event fires, you have two choices: set the ItemsSource property
immediately or launch an asynchronous process to do it. Setting the ItemsSource property
immediately makes sense if you have the list of suggestions on hand or you can generate them
quickly. The list of suggestions will then appear in the drop-down list right away.
But in many situations, you’ll need a potentially time-consuming step to get the list of
suggestions, such as performing a series of calculations or querying a web service. In this
situation, you need to launch an asynchronous process. Although you can accomplish this with
the multithreading support that’s described in Chapter 19, you won’t necessarily need to. Some
Silverlight features have built-in asynchronous support. This is the case with Silverlight’s
implementation of web services, which is hard-wired to use asynchronous calls exclusively.
When using an asynchronous operation, you need to explicitly cancel the normal
processing in the Populating event handler, by setting PopulatingEventArgs.Cancel to true. You
can then launch the asynchronous operation. The following example gets the suggestion list
asynchronously from a web service. (You’ll learn much more about coding and consuming web
services in Chapter 15. For now, you can review the example code and the downloadable
project with this chapter.)
private void acbProduct_Populating(object sender, PopulatingEventArgs e)
{
CHAPTER 5 ■ ELEMENTS
174
// Signal that the task is being performed asynchronously.
e.Cancel = true;
// Create the web service object.
ProductAutoCompleteClient service = new ProductAutoCompleteClient();
// Attach an event handler to the completion event.
service.GetProductMatchesCompleted += GetProductMatchesCompleted;
// Call the web service (asynchronously).
service.GetProductMatchesAsync(e.Parameter);
}
On the web server, the code in a GetProductMathes() web method runs and retrieves
the matches:
public string[] GetProductMatches(string inputText)
{
// Get the products (for example, from a server-side database).
Product[] products = GetProducts();
// Create a collection of matches.
List<string> productMatches = new List<string>();
foreach (Product product in products)
{
// See if this is a match.
if ((product.ProductName.StartsWith(inputText)) ||
(product.ProductCode.Contains(inputText)))
{
productMatches.Add(product.ProductName);
}
}
// Return the list of matches.
return productMatches.ToArray();
}
When the asynchronous operation finishes and you receive the result in your
Silverlight application, you fill the ItemsSource property with the list of suggestions. Then, you
must call the PopulateComplete() method to notify the AutoCompleteBox that the new data has
arrived. Here’s the callback handler that does the job in the current example:
private void GetProductMatchesCompleted(object sender,
GetProductMatchesCompletedEventArgs e)
{
// Check for a web service error.
if (e.Error != null)
{
lblStatus.Text = e.Error.Message;
return;
}
// Set the suggestions.
CHAPTER 5 ■ ELEMENTS
175
acbProducts.ItemsSource = e.Result;
// Notify the control that the data has arrived.
acbProducts.PopulateComplete();
}
When filling the AutoCompleteBox with a time-consuming or asynchronous step,
there are two properties you may want to adjust: MinimumPrefixLength and
MinimumPopupDelay. MinimumPrefixLength determines how much text must be typed in
before the AutoCompleteBox gives its suggestions. Ordinarily, the AutoCompleteBox offers
suggestions after the first letter is entered. If you want it to wait for three letters (the standard
used by many of the Ajax-powered auto-completion text boxes that you’ll find on the Web), set
MinimumPrefixLength to 3. Similarly, you can force the AutoCompleteBox to hold off until a
certain interval of time has passed since the user’s last keystroke using the
MinimumPopulateDelay property. This way, you won’t waste time with a flurry of overlapping
calls to a slow web service. Of course, this doesn’t necessarily determine how long it takes for
the suggestions to appear–that depends on the wait before initiating the query and then the
time needed to contact the web server and receive a response.
Range-Based Controls
Silverlight includes three controls that use the concept of a range. These controls take a
numeric value that falls in between a specific minimum and maximum value. These controls–
ScrollBar, Slider, and ProgressBar–derive from the RangeBase class (which itself derives from
the Control class). The RangeBase class adds a ValueChanged event, a Tooltip property, and the
range properties shown in Table 5-5.
Table 5-5. Properties of the RangeBase Class
Name Description
Value This is the current value of the control (which must fall between the minimum
and maximum). By default, it starts at 0. Contrary to what you might expect,
Value isn’t an integer–it’s a double, so it accepts fractional values. You can
react to the ValueChanged event if you want to be notified when the value is
changed.
Maximum This is the upper limit (the largest allowed value). The default value is 1.
Minimum This is the lower limit (the smallest allowed value). The default value is 0.
SmallChange This is the amount the Value property is adjusted up or down for a “small
change.” The meaning of a small change depends on the control (and may not
be used at all). For the ScrollBar and Slider, this is the amount the value
changes when you use the arrow keys. For the ScrollBar, you can also use the
arrow buttons at either end of the bar. The default SmallChange is 0.1.
CHAPTER 5 ■ ELEMENTS
176
Name Description
LargeChange This is the amount the Value property is adjusted up or down for a “large
change.” The meaning of a large change depends on the control (and may not
be used at all). For the ScrollBar and Slider, this is the amount the value
changes when you use the Page Up and Page Down keys or when you click the
bar on either side of the thumb (which indicates the current position). The
default LargeChange is 1.
Ordinarily, there’s no need to use the ScrollBar control directly. The higher-level
ScrollViewer control, which wraps two ScrollBar controls, is typically much more useful. (The
ScrollViewer was covered in Chapter 3.) However, the Slider and ProgressBar are more useful
on their own.
The Slider
The Slider is a specialized control that’s occasionally useful. You might use it to set numeric
values in situations where the number itself isn’t particularly significant. For example, it makes
sense to set the volume in a media player by dragging the thumb in a slider bar from side to
side. The general position of the thumb indicates the relative loudness (normal, quiet, loud),
but the underlying number has no meaning to the user.
Here’s an example that creates the horizontal slider shown in Figure 5-16:
<Slider Orientation="Horizontal" Minimum="0" Maximum="10" Width="100" />
Unlike WPF, the Silverlight slider doesn’t provide any properties for adding tick marks.
However, as with any control, you can change its appearance while leaving its functionality
intact using the control template feature described in Chapter 13.
Figure 5-16. A basic slider
The ProgressBar
The ProgressBar indicates the progress of a long-running task. Unlike the slider, the
ProgressBar isn’t user interactive. Instead, it’s up to your code to periodically increment the
CHAPTER 5 ■ ELEMENTS
177
Value property. By default, the Minimum value of a ProgressBar is 0, and the Maximum value is
100, so the Value corresponds to the percentage of work done. You’ll see an example with the
ProgressBar in Chapter 6, with a page that downloads a file from the Web and shows its
progress on the way.
One neat trick that you can perform with the ProgressBar is using it to show a longrunning status indicator, even if you don’t know how long the task will take. You do this by
setting the IsIndeterminate property to true:
<ProgressBar Height="18" Width="200" IsIndeterminate="True"></ProgressBar>
When setting IsIndeterminate, you no longer use the Minimum, Maximum, and Value
properties. No matter what values these properties have, the ProgressBar will show a hatched
pattern that travels con-tinuously from left to right. This pattern indicates that there’s work in
progress, but it doesn’t provide any information about how much progress has been made so
far.
Date Controls
Silverlight adds two date controls, neither of which exists in the WPF control library. Both are
designed to allow the user to choose a single date.
The Calendar control displays a calendar that’s similar to what you see in the Windows
operating system (for example, when you configure the system date). It shows a single month at
a time and allows you to step through from month to month (by clicking the arrow buttons) or
jump to a specific month (by clicking the month header to view an entire year, and then
clicking the month).
The DatePicker requires less space. It’s modeled after a simple text box, which holds a
date string in long or short date format. However, the DatePicker provides a drop-down arrow
that, when clicked, pops open a full calendar view that’s identical to that shown by the Calendar
control. This pop-up is displayed over top of any other content, just like a drop-down combo
box.
Figure 5-17 shows the two display modes that the Calendar supports, and the two date
formats that the DatePicker allows.
CHAPTER 5 ■ ELEMENTS
178
Figure 5-17. The Calendar and DatePicker
The Calendar and DatePicker include properties that allow you to determine which
dates are shown and which dates are selectable (provided they fall in a contiguous range). Table
5-6 lists the properties you can use.