Does my code demonstrate good WPF practice?
我正在启动一个WPF项目,刚刚完成了UI的基础,但它看起来非常复杂,所以我不确定是否以正确的方式进行了布局。我不想开始开发后端系统,也不想意识到我做错了前端系统,让自己的生活更加艰难。
从
本质上,它是一个一周的日历(7天,周一到周日,默认为当前的一周),最终会链接到数据库,如果我在这一天有约会,它会在相关的一天显示出来。
我选择了网格而不是ListView,因为它的工作方式是,我不会将结果绑定到集合或这些行中的任何内容。相反,我将在画布中为每一个事件填充一个组合框(还没有放到代码中),在选择时,它将向我显示更多的细节。
XAML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | <Window x:Class="WOW_Widget.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:Extensions="clr-namespace:WOW_Widget" DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="Window1" Height="239" Width="831"> <Window.Resources> <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="1.0" Color="White"/> <GradientStop Offset="0.0" Color="LightSlateGray"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="grdDayHeader" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="0.0" Color="Peru" /> <GradientStop Offset="1.0" Color="White" /> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="grdToday" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="0.0" Color="LimeGreen"/> <GradientStop Offset="1.0" Color="DarkGreen" /> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <Style TargetType="{x:Type GridViewColumnHeader}"> <Setter Property="Background" Value="Khaki" /> </Style> <Style x:Key="DayHeader" TargetType="{x:Type Label}"> <Setter Property="Background" Value="{StaticResource grdDayHeader}" /> <Setter Property="Width" Value="111" /> <Setter Property="Height" Value="25" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> </Style> <Style x:Key="DayField"> <Setter Property="Canvas.Width" Value="111" /> <Setter Property="Canvas.Height" Value="60" /> <Setter Property="Canvas.Background" Value="White" /> </Style> <Style x:Key="Today"> <Setter Property="Canvas.Background" Value="{StaticResource grdToday}" /> </Style> <Style x:Key="CalendarColSpacer"> <Setter Property="Canvas.Width" Value="1" /> <Setter Property="Canvas.Background" Value="Black" /> </Style> <Style x:Key="CalendarRowSpacer"> <Setter Property="Canvas.Height" Value="1" /> <Setter Property="Canvas.Background" Value="Black" /> </Style> </Window.Resources> <Grid Background="{StaticResource NormalBrush}"> <Border BorderBrush="Black" BorderThickness="1" Width="785" Height="86" Margin="12,12,12,104"> <Canvas Height="86" Width="785" VerticalAlignment="Top"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Grid.Column="0" Grid.Row="0" Content="Monday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="1" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="2" Grid.Row="0" Content="Tuesday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="3" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="4" Grid.Row="0" Content="Wednesday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="5" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="6" Grid.Row="0" Content="Thursday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="7" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="8" Grid.Row="0" Content="Friday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="9" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="10" Grid.Row="0" Content="Saturday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="11" Grid.RowSpan="3" Grid.Row="0" Style="{StaticResource CalendarColSpacer}" /> <Label Grid.Column="12" Grid.Row="0" Content="Sunday" Style="{StaticResource DayHeader}" /> <Canvas Grid.Column="0" Grid.ColumnSpan="13" Grid.Row="1" Style="{StaticResource CalendarRowSpacer}" /> <Canvas Grid.Column="0" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblMondayDate" /> </Canvas> <Canvas Grid.Column="2" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblTuesdayDate" /> </Canvas> <Canvas Grid.Column="4" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblWednesdayDate" /> </Canvas> <Canvas Grid.Column="6" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblThursdayDate" /> </Canvas> <Canvas Grid.Column="8" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblFridayDate" /> </Canvas> <Canvas Grid.Column="10" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblSaturdayDate" /> </Canvas> <Canvas Grid.Column="12" Grid.Row="2" Margin="0" Style="{StaticResource DayField}"> <Label Name="lblSundayDate" /> </Canvas> </Grid> </Canvas> </Border> <Canvas Height="86" HorizontalAlignment="Right" Margin="0,0,12,12" Name="canvas1" VerticalAlignment="Bottom" Width="198"></Canvas> </Grid> </Window> |
反恐精英:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public partial class Window1 : Window { private DateTime today = new DateTime(); private Label[] Dates = new Label[7]; public Window1() { DateTime start = today = DateTime.Now; int day = (int)today.DayOfWeek; while (day != 1) { start = start.Subtract(new TimeSpan(1, 0, 0, 0)); day--; } InitializeComponent(); Dates[0] = lblMondayDate; Dates[1] = lblTuesdayDate; Dates[2] = lblWednesdayDate; Dates[3] = lblThursdayDate; Dates[4] = lblFridayDate; Dates[5] = lblSaturdayDate; Dates[6] = lblSundayDate; FillWeek(start); } private void FillWeek(DateTime start) { for (int d = 0; d < Dates.Length; d++) { TimeSpan td = new TimeSpan(d, 0, 0, 0); DateTime _day = start.Add(td); if (_day.Date == today.Date) { Canvas dayCanvas = (Canvas)Dates[d].Parent; dayCanvas.Style = (Style)this.Resources["Today"]; } Dates[d].Content = (int)start.Add(td).Day; } } } |
我会说,不,你这样做是不对的。你做了太多的工作,让WPF做的太少。您应该使用数据绑定和一个
在这个例子中,我使用了
在WPF中,使用
并不是所有看起来像网格的东西都需要使用
这是我对你提供的东西的修改。在我看来,结果和你的差不多,但它大约是XAML的一半(不算画笔),而且修改起来更容易。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="{DynamicResource NormalBrush}"> <Page.Resources> <XmlDataProvider x:Key="Days" XPath="Days"> <x:XData> <Days xmlns=""> <Day Name="Sunday" Date="03/14/2010"/> <Day Name="Monday" Date="03/15/2010"/> <Day Name="Tuesday" Date="03/16/2010"/> <Day Name="Wednesday" Date="03/17/2010"/> <Day Name="Thursday" Date="03/18/2010"/> <Day Name="Friday" Date="03/19/2010"/> <Day Name="Saturday" Date="03/20/2010"/> </Days> </x:XData> </XmlDataProvider> <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="1.0" Color="White"/> <GradientStop Offset="0.0" Color="LightSlateGray"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="DayHeaderBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="0.0" Color="Peru" /> <GradientStop Offset="1.0" Color="White" /> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> </Page.Resources> <Grid Margin="50"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel Orientation="Horizontal"> <ItemsControl ItemsSource="{Binding Source={StaticResource Days}, XPath=Day}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical" Background="White"> <Border BorderBrush="Black" BorderThickness="1,1,0,0" Background="{StaticResource DayHeaderBrush}"> <TextBlock Margin="30,10" HorizontalAlignment="Center" Text="{Binding XPath=@Name}"/> </Border> <Border BorderBrush="Black" BorderThickness="1,1,0,0"> <TextBlock Margin="30,10" Height="50" HorizontalAlignment="Center" Text="{Binding XPath=@Date}"/> </Border> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Border BorderBrush="Black" BorderThickness="0,0,1,0"/> </StackPanel> </Grid> </Page> |
我不知道你的项目会有多大,但在开始WPF时,我能给你的最大建议是研究Prism框架:
http://www.codeplex.com/compositewpf
http://msdn.microsoft.com/en-us/magazine/cc785479.aspx
它是一个优秀的框架,可以为您解决很多问题。
关于您的日历,我建议您让它成为一个可重用的、看起来不那么容易控制的工具,本文可以帮助您:
http://www.codeproject.com/kb/wpf/wpfoutlookcalendar.aspx
如果稍后决定使用绑定,则可以遵循MVVM模式。有关详细信息:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
如果您想分别显示每天的约会,可以使用"relaycommand"转到第二天。