定义数据类型

 1 public enum OrderSource
 2     {
 3         Phone,
 4         Internet,
 5         WalkIn,
 6         Fax,
 7     }
 8 
 9     public struct PizzaOrder
10     {
11         public OrderSource Source {get;set; }
12         public string PhoneNumber { get; set; }
13         public int Size { get; set; }
14         public bool IsDelivery { get; set; }
15         public PizzaToppings[] Toppings { get; set; }
16     }

定义模板

 1 <Application x:Class="AcmePizza.App"
 2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4     xmlns:local="clr-namespace:AcmePizza"
 5     StartupUri="Window1.xaml">
 6     <Application.Resources>
 7         <!--A reusable data template when binding to a collection of pizza orders.  this template is used in both the main window and 
 8         current order window, where it is scaled larger-->
 9         <DataTemplate x:Key="PizzaOrderTemplate">
10             <Canvas Width="200" Height="200">
11                 <Rectangle x:Name="orderRectangle" RadiusX="6" RadiusY="6" Width="200" Height="200" Fill="LightBlue" Opacity="60"/>
12                 <TextBlock Margin="10,10,0,0" Text="Phone:"/>
13                         <TextBlock Margin="50,10,0,0" FontWeight="Bold"  Text="{Binding Path=PhoneNumber}"/>
14                         <local:PizzaSizeCircle x:Name="pizzaSize" Canvas.Right="5" Canvas.Bottom="5" PizzaSize="17"/> 
15                         <Image x:Name="sourceIcon" Source="phonesource.ico" Canvas.Left="5" Canvas.Bottom="5"/>
16                         <ItemsControl Canvas.Top="40" Canvas.Left="30" ItemsSource="{Binding Path=Toppings}"/>
17                     </Canvas>
18             <DataTemplate.Triggers>
19                 <DataTrigger Binding="{Binding Path=IsDelivery}" Value="true">
20                     <DataTrigger.Setters>
21                         <Setter Property="Fill" TargetName="orderRectangle" Value="Pink"/>
22                     </DataTrigger.Setters>
23                 </DataTrigger>
24                 <DataTrigger Binding="{Binding Path=Size}" Value="11">
25                     <DataTrigger.Setters>
26                         <Setter Property="PizzaSize" TargetName="pizzaSize" Value="11"/>
27                     </DataTrigger.Setters>
28                 </DataTrigger>
29                 <DataTrigger Binding="{Binding Path=Size}" Value="13">
30                     <DataTrigger.Setters>
31                         <Setter Property="PizzaSize" TargetName="pizzaSize" Value="13"/>
32                     </DataTrigger.Setters>
33                 </DataTrigger>
34                 <DataTrigger Binding="{Binding Path=Source}" Value="{x:Static Member=local:OrderSource.Internet}">
35                     <Setter Property="Source" TargetName="sourceIcon" Value="internetsource.ico"/>
36                 </DataTrigger>
37                 <DataTrigger Binding="{Binding Path=Source}" Value="{x:Static Member=local:OrderSource.Phone}">
38                     <Setter Property="Source" TargetName="sourceIcon" Value="phonesource.ico"/>
39                 </DataTrigger>
40                 <DataTrigger Binding="{Binding Path=Source}" Value="{x:Static Member=local:OrderSource.Fax}">
41                     <Setter Property="Source" TargetName="sourceIcon" Value="faxsource.ico"/>
42                 </DataTrigger>
43                 <DataTrigger Binding="{Binding Path=Source}" Value="{x:Static Member=local:OrderSource.WalkIn}">
44                     <Setter Property="Source" TargetName="sourceIcon" Value="walkinsource.ico"/>
45                 </DataTrigger>
46             </DataTemplate.Triggers>
47         </DataTemplate>
48     </Application.Resources>
49 </Application>

使用模板

 1 <Window x:Class="AcmePizza.Window1"
 2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4     xmlns:local="clr-namespace:AcmePizza"
 5     Title="Acme Pizza Co. - Current Orders" Height="428" Width="1038"
 6     Loaded="Window_Loaded" WindowState="Maximized" WindowStartupLocation="CenterScreen" ResizeMode="CanResize"
 7     >
 8     <Grid>
 9         <Grid.RowDefinitions>
10             <RowDefinition Height="55"/>
11             <RowDefinition Height="243*"/>
12         </Grid.RowDefinitions>
13         <Grid.ColumnDefinitions>
14             <ColumnDefinition Width="539"/>
15             <ColumnDefinition Width="477*" />
16         </Grid.ColumnDefinitions>
17 
18         <ItemsControl x:Name="ordersList" ItemsSource="{Binding}" ItemTemplate="{StaticResource PizzaOrderTemplate}"
19                       Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" Margin="0,0,0,0">
20             <ItemsControl.ItemsPanel>
21                     <ItemsPanelTemplate>
22                     <WrapPanel/>
23                 </ItemsPanelTemplate>
24             </ItemsControl.ItemsPanel>
25             <ItemsControl.ItemContainerStyle>
26                 <Style>
27                     <Setter Property="Control.Width" Value="205"/>
28                     <Setter Property="Control.Height" Value="205"/>
29                     <Setter Property="Control.Margin" Value="2.5"/>
30                 </Style>
31             </ItemsControl.ItemContainerStyle>
32         </ItemsControl>
33         <TextBlock Height="59" Name="textBlock1" VerticalAlignment="Top" Text="Acme Pizza Co." Foreground="Coral" FontSize="38" Margin="10,0,202,0" />
34         <TextBlock FontSize="38" Foreground="LightGreen" TextAlignment="Right" Name="textBlock2" Text="Current Orders" Margin="198,0,0,0" Grid.Column="1" />
35         <Image Height="55" Margin="0,4,201,0" 
36                    Name="image1" Stretch="UniformToFill" VerticalAlignment="Top" Source="pizzaicon.png" HorizontalAlignment="Right" Width="62" />
37         <Button Name="processNextOrderButton" Click="processNextOrderButton_Click" Margin="0,13,0,12" HorizontalAlignment="Right" Width="164">Process Next Order</Button>
38     </Grid>
39 </Window>

绑定数据源

 1 public partial class Window1 : Window
 2     {
 3         private IProducerConsumerCollection<PizzaOrder> m_orders;
 4         private static Random m_rand = new ThreadSafeRandom();
 5 
 6         public Window1()
 7         {
 8             InitializeComponent();
 9 
10             // intialize the bindable collection and set it as the data context
11             var orders = new ObservableConcurrentCollection<PizzaOrder>();
12             // store the observable collection as an explicity producer consumer 
13             // collection that has tryadd and tryremove operations
14             m_orders = orders;
15             // set the AcmePizza as the defaut
16             this.DataContext = orders;
17         }
18 
19         private void Window_Loaded(object sender, EventArgs e)
20         {
21             // launch four threads that mimic various sources
22             Task.Factory.StartNew(() => { OrdererThread(OrderSource.Fax); }, TaskCreationOptions.AttachedToParent);
23             Task.Factory.StartNew(() => { OrdererThread(OrderSource.Internet); }, TaskCreationOptions.AttachedToParent);
24             Task.Factory.StartNew(() => { OrdererThread(OrderSource.Phone); }, TaskCreationOptions.AttachedToParent);
25             Task.Factory.StartNew(() => { OrdererThread(OrderSource.WalkIn); }, TaskCreationOptions.AttachedToParent);
26         }
27 
28         private void OrdererThread(OrderSource source)
29         {
30             for ( int i = 0; i < 10; ++i )
31             {
32                 // submit random order
33                 m_orders.TryAdd( GenerateRandomOrder(source));
34                 // sleep for a random period
35                 Thread.Sleep(m_rand.Next(1000, 4001));
36             }
37         }
38 
39         private static PizzaOrder GenerateRandomOrder(OrderSource source)
40         {
41             // source
42             var order = new PizzaOrder { Source = source };
43             // delivery
44             order.IsDelivery = m_rand.Next(0, 2) == 0 ? true : false;
45             // phone number
46             var areaCode = m_rand.Next(0, 2) == 0 ? 425 : 206;
47             var firstThreeDigits = m_rand.Next(100, 1000);
48             var lastFourDigits = m_rand.Next(0, 10000);
49             order.PhoneNumber = String.Format("({0}) {1}-{2}", areaCode, firstThreeDigits, lastFourDigits.ToString("D4"));
50             // size
51             switch (m_rand.Next(0, 3))
52             {
53                 case 0: order.Size = 11; break;
54                 case 1: order.Size = 13; break;
55                 case 2: order.Size = 17; break;
56             }
57             // toppings
58             var availToppings = new List<PizzaToppings>(Enum.GetValues(typeof(PizzaToppings)).Cast<PizzaToppings>());
59             order.Toppings = new PizzaToppings[m_rand.Next(1, 5)];
60             for (int j = 0; j < order.Toppings.Length; ++j)
61             {
62                 var toppingIndex = m_rand.Next(0, availToppings.Count);
63                 order.Toppings[j] = availToppings[toppingIndex];
64                 availToppings.RemoveAt(toppingIndex);
65             }
66             return order;
67         }
68 
69         private void processNextOrderButton_Click(object sender, RoutedEventArgs e)
70         {
71             // attempt to get an order from the queue
72             PizzaOrder nextOrder;
73             if ( !m_orders.TryTake( out nextOrder ) )
74             {
75                 MessageBox.Show( "No orders available.  Please try again later.");
76                 return;
77             }
78             // if successful launch an order window
79             var currentOrderWindow = new CurrentOrderWindow(nextOrder);
80             currentOrderWindow.Show();
81         }
82     }

 

posted on 2019-06-09 12:09  xiyuxiyu  阅读(169)  评论(0)    收藏  举报