Scheduler for WPF
複数ユーザースケジュールの作成
Scheduler のカスタマイズ > 複数ユーザースケジュールの作成

Using Scheduler control, you can display schedules for multiple users. For this, you need to perform the following steps:

リソースと Scheduler コントロールの作成

この手順では、アプリケーションのリソースとデータ連結を作成します。また、Scheduler コントロールを追加してカスタマイズします。

次の手順に従います。

  1. Set up the application and configure the data source. For detailed steps, see クイックスタート.
  2. In the XAML view, add a <Window.Resources></Window.Resources> tag and add a set of <DataTemplate></DataTemplate> tags to it.
  3. Specify Key property in the <DataTemplate> tag to control the group header for the custom style using the following XAML markup:
    XAML
    コードのコピー
    <DataTemplate x:Key="myCustomGroupHeaderTemplate"></DataTemplate>
    
  4. Insert the following markup between the <DataTemplate> tags to add the DataTemplate resources:
    XAML
    コードのコピー
    <DataTemplate.Resources>
        <ControlTemplate x:Key="looklessButton" TargetType="{x:Type Button}">
            <Border>
                <ContentPresenter Margin="4,0" VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </DataTemplate.Resources>
    
  5. <DataTemplate.Resources> マークアップの下に、<Grid> </Grid> タグセットを追加します。最初の <Grid> タグをクリックし、タグに SnapsToDevicePixels="True" を追加します。
  6. 次のマークアップを使用して、グリッドコンポーネントに行および列定義を追加します。
    XAML
    コードのコピー
    <Grid.ColumnDefinitions>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition/>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
         <RowDefinition />
         <RowDefinition />
    </Grid.RowDefinitions>
    
  7. Create the C1BrushBuilders and the Border control for the Grid component by adding the following code beneath the <Grid.RowDefinitions></Grid.RowDefinitions> tags :
    XAML
    コードのコピー
    <c1:C1BrushBuilder x:Name="Background"  Input="{Binding Background}" />
    <c1:C1BrushBuilder x:Name="BorderBrush" Input="{Binding Background}" />
    <Border VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="2" Grid.RowSpan="2" 
            BorderThickness="1,0,1,0" BorderBrush="{Binding Output, ElementName=BorderBrush}" 
            Background="{Binding Output, ElementName=Background}" />
    
  8. Add the ButtonTemplates and the TextBlocks after the <Border/> tag to control the navigation and display for the Scheduler view:
    XAML
    コードのコピー
    <!-- 最初のグループに移動します -->
    <Button Template="{StaticResource looklessButton}" Content="|<<" Grid.Column="0" Grid.RowSpan="2" VerticalAlignment="Center" FontSize="12" Command="c1:C1Scheduler.NavigateToPreviousGroupCommand" CommandParameter="Home" CommandTarget="{Binding Scheduler}" Visibility="{Binding ShowPreviousButton, Converter={x:Static c1:BooleanToVisibilityConverter.Default}}" />
    <!-- 前のグループに移動します -->
    <Button Template="{StaticResource looklessButton}" Content="<" Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Center" FontSize="12" Command="c1:C1Scheduler.NavigateToPreviousGroupCommand" CommandTarget="{Binding Scheduler}" Visibility="{Binding ShowPreviousButton, Converter={x:Static c1:BooleanToVisibilityConverter.Default}}" />
    <!-- 次のグループに移動します -->
    <Button Template="{StaticResource looklessButton}" Content=">" Grid.Column="3" Grid.RowSpan="2" VerticalAlignment="Center" FontSize="12" Command="c1:C1Scheduler.NavigateToNextGroupCommand" CommandTarget="{Binding Scheduler}" Visibility="{Binding ShowNextButton, Converter={x:Static c1:BooleanToVisibilityConverter.Default}}" />
    <!-- 最後のグループに移動します -->
    <Button Template="{StaticResource looklessButton}" Content=">>|" Grid.Column="4" Grid.RowSpan="2" VerticalAlignment="Center" FontSize="12" Command="c1:C1Scheduler.NavigateToNextGroupCommand" CommandParameter="End" CommandTarget="{Binding Scheduler}" Visibility="{Binding ShowNextButton, Converter={x:Static c1:BooleanToVisibilityConverter.Default}}" />
    <TextBlock Foreground="{Binding Path=Scheduler.Foreground}" Margin="10,3" Grid.Column="2" Visibility="{Binding IsSelected, Converter={x:Static c1:BooleanToVisibilityConverter.Default}, ConverterParameter=Invert}" Text="{Binding DisplayName}" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <TextBlock Foreground="{Binding Path=Scheduler.Foreground}" Margin="10,3" Grid.Column="2" FontWeight="Bold" Visibility="{Binding IsSelected, Converter={x:Static c1:BooleanToVisibilityConverter.Default}}" Text="{Binding DisplayName}" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <!-- show additional info from the EmployeesRow -->
    <TextBlock Foreground="{Binding Path=Scheduler.Foreground}" Margin="10,3" Grid.Column="2" Grid.Row="1" Text="{Binding Path=Tag.Title}" VerticalAlignment="Center" HorizontalAlignment="Center" />
    
  9. TimeLine スタイルのグループヘッダーを制御するために、別の <DataTemplate> を作成します。
    XAML
    コードのコピー
    <!-- TimeLineスタイルに異なるグループヘッダーを使用します -->
    <DataTemplate x:Key="myCustomTimeLineGroupHeaderTemplate">
        <Grid IsHitTestVisible="False">
            <c1:C1BrushBuilder x:Name="Background"  Input="{Binding Background}" />
            <c1:C1BrushBuilder x:Name="BorderBrush"  Input="{Binding Background}" />
            <Border VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="4,1,0,1" BorderBrush="{Binding Output, ElementName=BorderBrush}" Background="{Binding Output, ElementName=Background}">
                <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
                    <TextBlock TextWrapping="Wrap" Foreground="{Binding Path=Scheduler.Foreground}" Margin="2" Text="{Binding DisplayName}" HorizontalAlignment="Center" />
                    <!-- show additional info from the EmployeesRow -->
                    <TextBlock TextWrapping="Wrap" Foreground="{Binding Path=Scheduler.Foreground}" Margin="2" Text="{Binding Path=Tag[Title]}" HorizontalAlignment="Center" />
                </StackPanel>
            </Border>
        </Grid>
    </DataTemplate>
    
  10. </Window.Resources> 終了タグの下に、<Grid> </Grid> タグセットを追加します。
  11. 次のマークアップを <Grid></Grid> タグの間に挿入します。
    XAML
    コードのコピー
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    
  12. <Grid>タグ内で次のコードを使用して、アプリケーションのツールバーを作成します。
    XAML
    コードのコピー
    <ToolBar Grid.Row="0" Grid.ColumnSpan="2">
        <RadioButton x:Name="btnDay" Content="Day" CommandTarget="{Binding ElementName=Scheduler}" Command="c1:C1Scheduler.ChangeStyleCommand" CommandParameter="{Binding Path=OneDayStyle, ElementName=Scheduler}" />
        <RadioButton x:Name="btnWorkWeek" Content="Work Week" CommandTarget="{Binding ElementName=Scheduler}" Command="c1:C1Scheduler.ChangeStyleCommand" CommandParameter="{Binding Path=WorkingWeekStyle, ElementName=Scheduler}" />
        <RadioButton x:Name="btnWeek" Content="Week" CommandTarget="{Binding ElementName=Scheduler}" Command="c1:C1Scheduler.ChangeStyleCommand" CommandParameter="{Binding Path=WeekStyle, ElementName=Scheduler}" />
        <RadioButton x:Name="btnMonth" Content="Month" CommandTarget="{Binding ElementName=Scheduler}" Command="c1:C1Scheduler.ChangeStyleCommand" CommandParameter="{Binding Path=MonthStyle, ElementName=Scheduler}" />
        <RadioButton x:Name="btnTimeLine" Content="Time Line" CommandTarget="{Binding ElementName=Scheduler}" Command="c1:C1Scheduler.ChangeStyleCommand" CommandParameter="{Binding Path=TimeLineStyle, ElementName=Scheduler}" />
    </ToolBar>
    <ListBox Grid.Column="0" Grid.Row="2" x:Name="lstUsers" MinHeight="100" Margin="2" ItemsSource="{Binding GroupItems, ElementName=Scheduler}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Margin="2" Content="{Binding}" Tag="{Binding}" IsChecked="{Binding IsChecked}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
  13. Add Scheduler and create the bindings for your application:
    XAML
    コードのコピー
    <c1:C1Scheduler x:Name="Scheduler" GroupBy="Owner" GroupHeaderTemplate="{StaticResource myCustomGroupHeaderTemplate}" GroupPageSize="2" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Style="{DynamicResource {ComponentResourceKey ResourceId=OneDayStyle, TypeInTargetAssembly=c1:C1Scheduler}}">
        <c1:C1Scheduler.Settings>
            <c1:C1SchedulerSettings FirstVisibleTime="07:00:00" AllowContactsEditing="False" AllowCategoriesEditing="False" AllowCategoriesMultiSelection="False" />
        </c1:C1Scheduler.Settings>
    </c1:C1Scheduler>
    

Back to Top

アプリケーションへのコードの追加

  1. Navigate to the Code view and Import the following namespaces:
    C#
    コードのコピー
    using C1.WPF.Schedule;
    using System.Collections.Specialized;
    using C1.C1Schedule;
    using System.Windows;
    using System.Windows.Controls;
    using SamplesName.C1NWindDataSetTableAdapters;
    
  2. Add the following fields in the MainWindow class:
    C#
    コードのコピー
    private AppointmentsTableAdapter appointmentsTableAdapter = new AppointmentsTableAdapter();
    private EmployeesTableAdapter employeesTableAdapter = new EmployeesTableAdapter();
    private CustomersTableAdapter customersTableAdapter = new CustomersTableAdapter();
    private C1NWindDataSet dataSet = new C1NWindDataSet();
    
  3. InitializeComponent() メソッドのすぐ下に、次のハンドラと呼び出しを追加して、データベースからデータを取得します。
    C#
    コードのコピー
    Scheduler.ReminderFire += new EventHandler(scheduler_ReminderFire);
    
    Scheduler.GroupItems.CollectionChanged += new NotifyCollectionChangedEventHandler(GroupItems_CollectionChanged);
    
    //データベースからデータを取得します
    this.employeesTableAdapter.Fill(dataSet.Employees);
    this.customersTableAdapter.Fill(dataSet.Customers);
    this.appointmentsTableAdapter.Fill(dataSet.Appointments);
    
  4. AppointmentStorage のマッピングと DataSource を設定します。
    C#
    コードのコピー
    //AppointmentStorages のマッピングとデータソースを設定します
    AppointmentStorage storage = Scheduler.DataStorage.AppointmentStorage;
    storage.Mappings.AppointmentProperties.MappingName = "Properties";
    storage.Mappings.Body.MappingName = "Description";
    storage.Mappings.End.MappingName = "End";
    storage.Mappings.IdMapping.MappingName = "AppointmentId";
    storage.Mappings.Location.MappingName = "Location";
    storage.Mappings.Start.MappingName = "Start";
    storage.Mappings.Subject.MappingName = "Subject";
    storage.Mappings.OwnerIndexMapping.MappingName = "Owner";
    storage.DataSource = dataSet.Appointments;
    
  5. OwnerStorage のマッピングと DataSource を設定します。
    C#
    コードのコピー
    //OwnerStorage のマッピングとデータソースを設定します
    ContactStorage ownerStorage = Scheduler.DataStorage.OwnerStorage;
    INotifyCollectionChanged)ownerStorage.Contacts).CollectionChanged += new NotifyCollectionChangedEventHandler(Owners_CollectionChanged);
    ownerStorage.Mappings.IndexMapping.MappingName = "EmployeeId";
    ownerStorage.Mappings.TextMapping.MappingName = "FirstName";
    ownerStorage.DataSource = dataSet.Employees;
    
  6. ContactStorage のマッピングと DataSource を設定します。
    C#
    コードのコピー
    //ContactStorage のマッピングとデータソースを設定します
    ContactStorage cntStorage = Scheduler.DataStorage.ContactStorage;
    ((INotifyCollectionChanged)cntStorage.Contacts).CollectionChanged += new NotifyCollectionChangedEventHandler(Contacts_CollectionChanged);
    cntStorage.Mappings.IdMapping.MappingName = "CustomerId";
    cntStorage.Mappings.TextMapping.MappingName = "CompanyName";
    cntStorage.DataSource = dataSet.Customers;
    
  7. Add the following code to set the IsChecked property of the btnDay, create StyleChanged event for the scheduler control and MainWindowLoaded event.
    C#
    コードのコピー
    btnDay.IsChecked = true;
    Scheduler.StyleChanged += new System.EventHandler<RoutedEventArgs>(Scheduler_StyleChanged);
    this.Loaded += MultiUser_Loaded;
    
  8. Add the following methods to update the group items, owners and contacts.
    C#
    コードのコピー
    void GroupItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
            foreach (SchedulerGroupItem group in Scheduler.GroupItems)
            {
                    if (group.Owner != null)
                    {
                            // SchedulerGroupItem.Tagプロパティをデータ行に設定します。 これにより、xamlのデータ行フィールドをバインドに使用できます
                            int index = (int)group.Owner.Key[0];
                            C1NWindDataSet.EmployeesRow row = dataSet.Employees.Rows.Find(index) as C1NWindDataSet.EmployeesRow;
                            group.Tag = row;
                    }
            }
    }
    
    void Owners_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                    foreach (Contact cnt in e.NewItems)
                    {
                            C1NWindDataSet.EmployeesRow row = dataSet.Employees.Rows.Find(cnt.Key[0]) as C1NWindDataSet.EmployeesRow;
                            if (row != null)
                            {
                                    // Contact.MenuCaptionをFirstNameおよびLastName文字列に設定します
                                    cnt.MenuCaption = row["FirstName"].ToString() + " " + row["LastName"].ToString();
                            }
                    }
            }
    }
    
    void Contacts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                    foreach (Contact cnt in e.NewItems)
                    {
                            C1NWindDataSet.CustomersRow row = dataSet.Customers.Rows.Find(cnt.Key[0]) as C1NWindDataSet.CustomersRow;
                            if (row != null)
                            {
                                    // Contact.MenuCaptionをCompanyNameおよびContactName文字列に設定します
                                    cnt.MenuCaption = row["CompanyName"].ToString() + " (" + row["ContactName"].ToString() + ")";
                            }
                    }
            }
    }
    
  9. Get the current window, save changes and prevent showing reminders using the following code:
    C#
    コードのコピー
    // 現在のウィンドウを取得します
                    private void MultiUser_Loaded(object sender, RoutedEventArgs e)
                    {
                            Window window = Window.GetWindow(this);
                window.Closing += Window_Closing;
                    }
                    // save changes
                    private void Window_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
            {
                            this.appointmentsTableAdapter.Update(dataSet.Appointments);
                    }
    
            // アラームを表示しないようにします
            private void scheduler_ReminderFire(object sender, ReminderActionEventArgs e)
                    {
                            e.Handled = true;
                    }
                    private void Scheduler_StyleChanged(object sender, RoutedEventArgs e)
                    {
                            if (Scheduler.Style == Scheduler.TimeLineStyle)
                            {
                                    // update group header (use different headers for TimeLine and other views)
                                    Scheduler.GroupHeaderTemplate = (DataTemplate)Resources["myCustomTimeLineGroupHeaderTemplate"];
                                    btnTimeLine.IsChecked = true;
                            }
                            else
                            {
                                    // グループヘッダーを更新します(TimeLineと他のビューに異なるヘッダーを使用します)
                                    Scheduler.GroupHeaderTemplate = (DataTemplate)Resources["myCustomGroupHeaderTemplate"];
                                    // 現在のC1Schedulerビューに従ってツールバーボタンの状態を更新します
                                    if (Scheduler.Style == Scheduler.WorkingWeekStyle)
                                    {
                                            btnWorkWeek.IsChecked = true;
                                    }
                                    else if (Scheduler.Style == Scheduler.WeekStyle)
                                    {
                                            btnWeek.IsChecked = true;
                                    }
                                    else if (Scheduler.Style == Scheduler.MonthStyle)
                                    {
                                            btnMonth.IsChecked = true;
                                    }
                                    else
                                    {
                                            btnDay.IsChecked = true;
                                    }
                            }
                    }
    

Back to Top

アプリケーションの実行

F5]キーを押してアプリケーションを実行します。

Back to Top