2010-03-12 5 views
4

Je commence un projet WPF, et je viens de terminer la base de l'interface utilisateur, cela semble très compliqué cependant, donc je ne suis pas sûr d'avoir fait le bon choix. Je ne veux pas commencer à développer le back-end et réaliser que j'ai mal fait le front, et rendre la vie plus difficile pour moi-même. DIVERS et CSS pour le style Ceci est très différent, et veut vraiment le faire dès le départ. Essentiellement, il s'agit d'un calendrier d'une semaine (7 jours, lundi-dimanche, par défaut à la semaine en cours.) Qui finira par se lier à un DB et si j'ai un rendez-vous pour quelque chose ce jour, il le montrera dans le jour pertinent.Mon code démontre-t-il une bonne pratique de WPF?

J'ai opté pour une grille plutôt que ListView en raison de la façon dont cela fonctionnera Je ne vais pas lier les résultats à une collection ou quoi que ce soit le long de ces lignes. Je vais plutôt remplir une zone de liste déroulante dans la toile pour chaque jour (encore à placer dans le code) pour chaque événement et sur la sélection, il me montrera plus de détails.

XAML:

 
<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> 

CS:

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 &lt; 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; 
     } 
    } 
} 
+3

Sauf si vous avez un message d'erreur spécifique ou d'une partie que vous êtes coincé, je dirais que ce genre de question serait mieux adaptée au [Code Review] (https://codereview.stackexchange.com/) site. –

Répondre

11

Je dirais que non, vous n'allez pas dans ce sens. Vous faites trop de travail et laissez WPF en faire trop peu. Vous devriez utiliser la liaison de données et un ItemsControl, et laisser WPF faire tout ce qu'il faut pour savoir où placer les choses et quoi y mettre.

  1. J'ai utilisé un XmlDataProvider dans cet exemple parce qu'il est la meilleure façon de montrer comment peut être utilisé de liaison de données sans écrire de code. Vous construisez probablement une classe de modèle de vue qui expose une collection d'objets avec des propriétés Name et Date et lie à une instance de cela. L'utilisation de mises en page pixel par pixel et Canvas est une mauvaise chose dans WPF, qui consiste à créer des interfaces utilisateur indépendantes de la résolution. Il est préférable de faire en sorte que le moteur de mise en page fasse tout ce travail.

  2. Tout ce qui ressemble à une grille ne doit pas être mis en page avec Grid. Il y a beaucoup, beaucoup moins de XAML si vous posez cette grille comme horizontale StackPanel. Cela vous évite de devoir visser avec les numéros de rangées et de colonnes. La seule raison pour laquelle ma mise en page utilise un Grid est de rendre la taille de la bordure à son contenu.

Voici ma reprise de ce que vous avez fourni. Pour moi, le résultat est à peu près le même que le vôtre, mais c'est environ la moitié du XAML (sans compter les pinceaux) et c'est beaucoup plus facile à modifier.

<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 [email protected]}"/> 
        </Border> 
        <Border BorderBrush="Black" BorderThickness="1,1,0,0"> 
         <TextBlock Margin="30,10" Height="50" HorizontalAlignment="Center" Text="{Binding [email protected]}"/> 
        </Border> 
        </StackPanel> 
       </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
      <Border BorderBrush="Black" BorderThickness="0,0,1,0"/> 
      </StackPanel> 
     </Grid> 
</Page> 
+0

Je voudrais ajouter que vous pourriez aussi envisager de créer un contrôle personnalisé (en le plaçant dans un style dans un dictionnaire de ressources): https: // www .tutorialspoint.com/wpf/wpf_custom_controls.htm à mi-chemin. – sondergard

3

Je ne sais pas la taille de votre projet va être, mais le plus grand conseil que je peux vous donner quand commence WPF est de regarder dans le cadre de PRISM:

http://www.codeplex.com/CompositeWPF

http://msdn.microsoft.com/en-us/magazine/cc785479.aspx

C'est un excellent cadre, et résout beaucoup de problèmes pour vous.

En ce qui concerne votre calendrier, je recommande ce qui en fait un réutilisable contrôle de correspondance moins, cet article peut vous aider:

http://www.codeproject.com/KB/WPF/WPFOutlookCalendar.aspx

+1

Pour les futurs lecteurs et les débutants de WPF, je suggère fortement de ne pas commencer par PRISM avant de comprendre les bases de WPF. En outre, "excellent cadre" est un peu subjectif. Je dirais que c'est un «cadre sub-pair» qui résout certains problèmes, mais en crée beaucoup d'autres. – UrbanEsc

+0

La plus grande astuce que je peux donner est d'éviter tout cadre PRISM – sam

3

Vous pouvez suivre le modèle MVVM si vous décidez d'utiliser la liaison . Pour plus de détails:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Vous pouvez utiliser le « RelayCommand » aller au jour suivant si vous souhaitez afficher les rendez-vous séparément pour chaque jour.

Questions connexes