Мой код демонстрирует хорошую практику WPF?

Я запускаю проект WPF и только что закончил основу UI, это кажется очень замысловатым, хотя, таким образом, я не уверен, обошел ли я разметку его правильным способом. Я не хочу добираться, чтобы начать разработать бэкенд и понимать, что я сделал переднюю сторону неправильно и делаю жизнь тяжелее для меня.

Происхождение из среды <DIV> и CSS для моделирования этого является существенно иным, и действительно хотят получить его с самого начала.

По существу это - один недельный календарь (7 дней, в понедельник-воскресенье, принимая значение по умолчанию к текущей неделе.), Который в конечном счете соединится к DB и если у меня есть назначение для чего-то в этот день, оно покажет его в соответствующий день.

Я выбрал Сетку, а не ListView из-за способа, которым он будет работать, я не буду связывать результаты с набором или чем-либо вдоль тех строк. Скорее я буду заполнять Поле комбинированного списка в холсте в течение каждого дня (все же, чтобы быть помещенным в код) для каждого события, и на выборе это покажет мне более подробную информацию.

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;
        }
    }
}
7
задан S.Orioli 25 October 2019 в 13:49
поделиться

3 ответа

Я бы сказал, нет, вы поступаете неправильно. Вы делаете слишком много работы и позволяете WPF делать слишком мало. Вы должны использовать привязку данных и ItemsControl , и позволить WPF делать всю тяжелую работу по выяснению, куда и что помещать.

  1. В этом примере я использовал XmlDataProvider , потому что это самый простой способ продемонстрировать, как можно использовать привязку данных без написания кода. Вы, вероятно, создадите класс модели представления, который предоставит коллекцию объектов со свойствами Name и Date и привяжется к экземпляру этого.

  2. Использование Canvas и попиксельных макетов - это плохая вещь в WPF, которая связана с построением пользовательских интерфейсов, не зависящих от разрешения. Гораздо лучше сделать так, чтобы всю эту работу делал механизм компоновки.

  3. Не все, что выглядит как сетка, нужно размещать с помощью Grid .Если вы разместите эту сетку как горизонтальную StackPanel , то будет намного меньше XAML. Это избавит вас от необходимости возиться с номерами строк и столбцов. Единственная причина, по которой в моем макете используется сетка , заключается в том, чтобы установить размер границы для его содержимого.

Вот моя переработка того, что вы предоставили. На мой взгляд, результат выглядит почти так же, как ваш, но это примерно вдвое меньше XAML (не считая кистей), и его легче изменить.

<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>
19
ответ дан 6 December 2019 в 06:24
поделиться

Вы можете следовать шаблону MVVM, если позже решите использовать привязку. Для получения дополнительной информации:

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

Вы можете использовать 'RelayCommand', чтобы перейти на следующий день, если вы хотите показать встречи отдельно на каждый день.

4
ответ дан 6 December 2019 в 06:24
поделиться

Я не знаю, насколько большим будет ваш проект, но самый большой совет, который я могу дать вам при запуске WPF, это обратить внимание на фреймворк PRISM:

http://www.codeplex.com/CompositeWPF

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

Это отличный фреймворк, который решит для вас множество проблем.

Что касается вашего календаря, я бы рекомендовал сделать его повторно используемым элементом управления без внешнего вида, эта статья может помочь вам:

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

5
ответ дан 6 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: