Custom Appointment : Required validator for a combobox inside EditAppointmentDialog

6 posts, 0 answers
  1. Maxence
    Maxence avatar
    21 posts
    Member since:
    Aug 2011

    Posted 04 Oct 2011 Link to this post

    Hi Telerik team,

    i created a custom appointment :

    public class Imputation: Appointment
     {
     
         private Processus process;
         public Processus Process
         {
             get
             {
                 return this.Storage<Imputation>().process;
             }
             set
             {
                 var storage = this.Storage<Imputation>();
                 if (storage.process != value)
                 {
                     storage.process = value;
                     this.OnPropertyChanged(() => this.Process);
                 }
             }
         }
     
         private Projet project;
         public Projet Project
         {
             get
             {
                 return this.Storage<Imputation>().project;
             }
             set
             {
                 var storage = this.Storage<Imputation>();
                 if (storage.project != value)
                 {
                     storage.project = value;
                     this.OnPropertyChanged(() => this.Project);
                 }
             }
         }
     
         private Metier work;
         public Metier Work
         {
             get
             {
                 return this.Storage<Imputation>().work;
             }
             set
             {
                 var storage = this.Storage<Imputation>();
                 if (storage.work != value)
                 {
                     storage.work = value;
                     this.OnPropertyChanged(() => this.Work);
                 }
             }
         }
     
         private bool isMeeting;
         public bool IsMeeting
         {
             get
             {
                 return this.Storage<Imputation>().isMeeting;
             }
             set
             {
                 var storage = this.Storage<Imputation>();
                 if (storage.isMeeting != value)
                 {
                     storage.isMeeting = value;
                     this.OnPropertyChanged(() => this.IsMeeting);
                 }
             }
         }
     
         private bool isAdditionalHour;
         public bool IsAdditionalHour
         {
             get
             {
                 return this.Storage<Imputation>().isAdditionalHour;
             }
             set
             {
                 var storage = this.Storage<Imputation>();
                 if (storage.isAdditionalHour != value)
                 {
                     storage.isAdditionalHour = value;
                     this.OnPropertyChanged(() => this.IsAdditionalHour);
                 }
             }
         }
     
          
     
         public override IAppointment Copy()
         {
             var newImputation = new Imputation();
             newImputation.CopyFrom(this);
             return newImputation;
         }
         public override void CopyFrom(IAppointment other)
         {
              
             var imputation = other as Imputation;
             if (imputation != null)
             {
                 this.IsMeeting = imputation.IsMeeting;
                 this.IsAdditionalHour = imputation.IsMeeting;
                 this.Process = imputation.Process;
                 this.Project = imputation.Project;
                 this.Work = imputation.Work;
                  
             }
             base.CopyFrom(other);
              
         }
     }

    and here the content of editappointmenttemplate :

    <ControlTemplate x:Key="EditAppointmentTemplate" TargetType="telerik:SchedulerDialog">
               <Grid>
                   <Grid.RowDefinitions>
                       <RowDefinition Height="Auto"/>
                       <RowDefinition Height="Auto"/>
                       <RowDefinition Height="*"/>
                       <RowDefinition Height="Auto"/>
                       <RowDefinition Height="Auto"/>
                       <RowDefinition Height="Auto"/>
                   </Grid.RowDefinitions>
                   <telerik:RadToolBar x:Name="AppointmentToolbar" GripVisibility="Collapsed" Margin="-1 -1 -1 3" Grid.Row="0" telerik:StyleManager.Theme="{StaticResource Theme}">
                       <telerik:RadButton x:Name="EditRecurrenceButton" Command="telerik:RadScheduleViewCommands.EditRecurrenceRule" Visibility="{Binding CanEditParentAppointment, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
                           <ToolTipService.ToolTip>
                               <ToolTip telerik:LocalizationManager.ResourceKey="EditRecurrence" telerik:StyleManager.Theme="{StaticResource Theme}"/>
                           </ToolTipService.ToolTip>
                           <StackPanel Margin="2 0" Orientation="Horizontal">
                               <Image Margin="2 0" Source="{StaticResource EditAppointmentTemplate_Recurrence}" Stretch="None"/>
                               <TextBlock Foreground="{StaticResource RadScheduleForeground}" Margin="4 0" telerik:LocalizationManager.ResourceKey="EditRecurrence"/>
                           </StackPanel>
                       </telerik:RadButton>
                       <telerik:RadButton x:Name="EditParentAppointmentButton" Command="telerik:RadScheduleViewCommands.EditParentAppointment" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Visibility="{Binding CanEditParentAppointment, Converter={StaticResource BooleanToVisibilityConverter}}">
                           <ToolTipService.ToolTip>
                               <TextBlock telerik:LocalizationManager.ResourceKey="EditParentAppointment" telerik:StyleManager.Theme="{StaticResource Theme}"/>
                           </ToolTipService.ToolTip>
                           <TextBlock Foreground="{StaticResource RadScheduleForeground}" Margin="4 0" telerik:LocalizationManager.ResourceKey="EditParentAppointment"/>
                       </telerik:RadButton>
                        
                   </telerik:RadToolBar>
                   <Border x:Name="AppointmentCategory" Background="{Binding SelectedItem.CategoryBrush, ElementName=PART_Categories}" CornerRadius="3" Height="20" Margin="6 6" Grid.Row="1" Visibility="{Binding SelectedItem, Converter={StaticResource NullToVisibilityConverter}, ElementName=PART_Categories}">
                       <TextBlock Margin="6 0" Text="{Binding SelectedItem.DisplayName, ElementName=PART_Categories}" VerticalAlignment="Center"/>
                   </Border>
                   <Grid x:Name="Details" Margin="6" Grid.Row="2">
                       <Grid.Resources>
                           <telerik:InputMode x:Key="RadDateTimePickerInputModeDatePicker">DatePicker</telerik:InputMode>
                       </Grid.Resources>
                       <Grid.ColumnDefinitions>
                           <ColumnDefinition Width="135"/>
                           <ColumnDefinition Width="*"/>
                           <ColumnDefinition Width="*"/>
                       </Grid.ColumnDefinitions>
                       <Grid.RowDefinitions>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="*"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                           <RowDefinition Height="Auto"/>
                       </Grid.RowDefinitions>
                       <ItemsControl Grid.Row="0" Grid.Column="2" Grid.RowSpan="6" Margin="6"   ItemsSource="{Binding Path=SelectedItem.Taches, ElementName=cmbProcessus}">
                           <ItemsControl.ItemTemplate>
                               <DataTemplate>     
                                       <TextBlock TextWrapping="Wrap">
                                                <Run>• </Run><Run Text="{Binding Libelle}"/>
                                       </TextBlock>
                               </DataTemplate>
                           </ItemsControl.ItemTemplate>
                       </ItemsControl>
                       <TextBlock Grid.Row="0" Grid.Column="0" Margin="6"  Text="Processus"/>
                       <telerik:RadComboBox x:Name="cmbProcessus" Grid.Row="0"  Grid.Column="1" ItemsSource="{Binding ElementName=RecurrentScheduleView, Path=DataContext.Processus, Mode=TwoWay}" SelectedValue="{Binding Path=Occurrence.Appointment.Process, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" DisplayMemberPath="Libelle"  Margin="2 1" telerik:StyleManager.Theme="{StaticResource Theme}" Loaded="cmbProcessus_Loaded">
                            
                           <ToolTipService.ToolTip>
                               <ItemsControl ItemsSource="{Binding Path=SelectedItem.Taches, ElementName=cmbProcessus}">
                                   <ItemsControl.ItemTemplate>
                                       <DataTemplate>
                                           <TextBlock>
                                                <Run>• </Run><Run Text="{Binding Libelle}"/>
                                           </TextBlock>
                                       </DataTemplate>
                                   </ItemsControl.ItemTemplate>
                               </ItemsControl>
     
                           </ToolTipService.ToolTip>
                       </telerik:RadComboBox>
                       <TextBlock Grid.Row="1" Grid.Column="0" Margin="6"  Text="Métier" />
                       <telerik:RadComboBox x:Name="cmbWorks" Grid.Row="1"  Grid.Column="1" ItemsSource="{Binding ElementName=RecurrentScheduleView, Path=DataContext.Metiers, Mode=TwoWay}" SelectedValue="{Binding Path=Occurrence.Appointment.Work, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" DisplayMemberPath="Libelle" Margin="2 1" Loaded="cmbWorks_Loaded" telerik:StyleManager.Theme="{StaticResource Theme}"/>
                       <TextBlock Grid.Row="2" Grid.Column="0" Margin="6"  Text="Projet"/>
                       <telerik:RadComboBox Grid.Row="2" Grid.Column="1" x:Name="cmbProjects"   ItemsSource="{Binding ElementName=RecurrentScheduleView, Path=DataContext.Projets, Mode=TwoWay}" SelectedValue="{Binding Path=Occurrence.Appointment.Project, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" DisplayMemberPath="Libelle" Margin="2 1" Loaded="cmbProjects_Loaded" telerik:StyleManager.Theme="{StaticResource Theme}"/>
     
                       <TextBlock Grid.Row="3" Grid.Column="0"  Margin="6"  telerik:LocalizationManager.ResourceKey="StartTime"/>
                       <telerik:RadDateTimePicker Grid.Row="3" Grid.Column="1" TimeInterval="0:30" Culture="{Binding DefaultCulture, Source={StaticResource LocalizationManager}}"  IsReadOnly="{Binding IsReadOnly}" IsEnabled="{Binding IsNotRecurrent}" Margin="3"  SelectedValue="{Binding ActualStart, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnDataErrors=true}" telerik:StyleManager.Theme="{StaticResource Theme}">
                           <telerik:RadDateTimePicker.InputMode>
                               <Binding Converter="{StaticResource BoolToInputModeConverter}" Path="IsAllDayEvent">
                                   <Binding.ConverterParameter>
                                       <telerik:InputMode>DatePicker</telerik:InputMode>
                                   </Binding.ConverterParameter>
                               </Binding>
                           </telerik:RadDateTimePicker.InputMode>
                       </telerik:RadDateTimePicker>
                       <TextBlock  Grid.Row="4" Grid.Column="0" Margin="6" telerik:LocalizationManager.ResourceKey="EndTime" telerik:StyleManager.Theme="{StaticResource Theme}" VerticalAlignment="Center"/>
                       <telerik:RadDateTimePicker Grid.Row="4" Grid.Column="1" TimeInterval="0:30"  Culture="{Binding DefaultCulture, Source={StaticResource LocalizationManager}}"  IsReadOnly="{Binding IsReadOnly}" IsEnabled="{Binding IsNotRecurrent}" Margin="3"  SelectedValue="{Binding ActualEnd, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnDataErrors=true}" telerik:StyleManager.Theme="{StaticResource Theme}">
                           <telerik:RadDateTimePicker.InputMode>
                               <Binding Converter="{StaticResource BoolToInputModeConverter}" Path="IsAllDayEvent">
                                   <Binding.ConverterParameter>
                                       <telerik:InputMode>DatePicker</telerik:InputMode>
                                   </Binding.ConverterParameter>
                               </Binding>
                           </telerik:RadDateTimePicker.InputMode>
                       </telerik:RadDateTimePicker>
     
                       <TextBlock Grid.Row="5" Grid.Column="0" Margin="6"  Text="Reunion" />
                       <CheckBox Grid.Row="5" Grid.Column="1" Margin="3"  IsChecked="{Binding Occurrence.Appointment.IsMeeting, Mode=TwoWay}"/>
                       <TextBlock Grid.Row="6" Grid.Column="0" Margin="6"  Text="Heure supplémentaire" />
                       <CheckBox Grid.Row="6" Grid.Column="1" Margin="3"  IsChecked="{Binding Occurrence.Appointment.IsAdditionalHour, Mode=TwoWay}"/>
                        
     
                   </Grid>
                   <Grid Margin="3" Grid.Row="3" Visibility="{Binding ResourceTypesVisibility}">
                       <telerik:ItemsControl x:Name="PART_Resources" BorderBrush="{x:Null}" BorderThickness="0" HorizontalContentAlignment="Stretch" IsTabStop="false" ItemsSource="{Binding ResourceTypes}" ItemTemplateSelector="{StaticResource ResourcesEditorItemTemplateSelector}" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Margin="3" Visibility="{Binding ResourceTypesVisibility}" VerticalContentAlignment="Stretch"/>
                       <TextBlock HorizontalAlignment="Center" Margin="3" Text="You can only change the resources by opening the series" Visibility="{Binding ResourceTypesVisibility, Converter={StaticResource InvertedVisibilityConverter}}"/>
                   </Grid>
                   <StackPanel HorizontalAlignment="Right" Margin="13 6" Orientation="Horizontal" Grid.Row="4">
                       <telerik:RadButton Command="telerik:WindowCommands.Confirm" Margin="2" MinWidth="84" telerik:LocalizationManager.ResourceKey="Ok" telerik:RadWindow.ResponseButton="Accept" telerik:StyleManager.Theme="{StaticResource Theme}">
                           <ToolTipService.ToolTip>
                               <TextBlock telerik:LocalizationManager.ResourceKey="SaveAndClose" telerik:StyleManager.Theme="{StaticResource Theme}"/>
                           </ToolTipService.ToolTip>
                       </telerik:RadButton>
                       <telerik:RadButton Command="telerik:WindowCommands.Cancel" Margin="2" MinWidth="84" telerik:LocalizationManager.ResourceKey="Cancel" telerik:RadWindow.ResponseButton="Cancel" telerik:StyleManager.Theme="{StaticResource Theme}"/>
                   </StackPanel>
               </Grid>
           </ControlTemplate>

    I would like to add validation to be sure than the user doesn't leave the combobox named "cmbWorks" empty ? how to proceed ?

    I read this thread : http://www.telerik.com/community/forums/silverlight/scheduleview/ok-button-in-edit-appointment-dialog-window-is-disabled-for-new-appointment.aspx  , this one http://www.telerik.com/community/forums/silverlight/scheduleview/how-to-validate-appointment-property-in-editappointmentdialog.aspx and also some others  but it just added to my confusion :-( :

    so, how to add this validation (don't leave empty the combobox) to have a custom error message displaying and the ok button disabled  (just like it's the case if enddate < startdate) ?

    thanks by advance for your answer, Regards,

    Maxence
  2. Maxence
    Maxence avatar
    21 posts
    Member since:
    Aug 2011

    Posted 06 Oct 2011 Link to this post

    Hi,

    finally i found in sample projects on telerik installation folder the solution :

    for those interested, just implement the IDataErrorInfo interface :

    public class Imputation : Appointment, IDataErrorInfo


    then implement the validation => the names ("Project" , "Work" in this example) must correspond to your properties name :

    public string Error
    {
        get { return this.ValidateImputation(); }
    }
     
    private string ValidateImputation()
    {
        string errorString = this.ValidateProject();
     
        errorString += this.ValidateWork();
     
        return errorString;
    }
     
    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Project":
                    return this.ValidateProject();
                case "Work":
                    return this.ValidateWork();
            }
            return null;
        }
    }
     
    private string ValidateProject()
    {
        string errorString = String.Empty;
        if (this.Project == null)
        {
            errorString += "Le projet est requis";
        }
        return errorString;
    }
     
    private string ValidateWork()
    {
        string errorString = String.Empty;
        if (this.Work == null)
        {
            errorString += "Le métier est requis";
        }
        return errorString;
    }

    Regards,

    Maxence
  3. DevCraft banner
  4. Ivo
    Admin
    Ivo avatar
    390 posts

    Posted 07 Oct 2011 Link to this post

    Hello Maxence,

    I want to confirm this is the way to add validation to appointments dialog window.

    Regards,
    Ivo
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  5. Maxence
    Maxence avatar
    21 posts
    Member since:
    Aug 2011

    Posted 11 Oct 2011 Link to this post

    Hi Ivo,

    in fact i have a problem or perhaps it's a limitation when a validation must occurs on multiple fields. Here a scenario to explain :
    • an error message must appear for both "project" and "work" if both of them are null
    private string ValidateWork()
     {
        string errorString = String.Empty;
        if (this.Project == null && this.Work == null))
        {
            errorString += "Work or Project cannot be both empty";
        }
        return errorString;
    }
     
    private string ValidateProject()
     {
        string errorString = String.Empty;
        if (this.Project == null && this.Work == null))
        {
            errorString += "Work or Project cannot be both empty";
        }
        return errorString;
    }
    if i fill "Project" Field, the error message disapear (it's correct behavior) but...the one for "Work" remains (it's not correct behavior)

    Is there a way to force the re-validation of "Work" when a validation on "Project" occurs ?

    Regards,

    Maxence
  6. Ivo
    Admin
    Ivo avatar
    390 posts

    Posted 14 Oct 2011 Link to this post

    Hello Maxence,

    We reproduced this successfully at our side. We will need more time to investigate it. We will contact you next week with more details on this.

    All the best,
    Ivo
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  7. Maxence
    Maxence avatar
    21 posts
    Member since:
    Aug 2011

    Posted 16 Oct 2011 Link to this post

    Hi Ivo,

    thanks for the news. As a work around, i force the validation of the other element in the selectionchanged event of the combobox :

    private void cmbWorks_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
            {
                RadComboBox cmbWorks = sender as RadComboBox;
                Grid grid = cmbWorks.Parent as Grid;
                RadComboBox cmbProject = grid.FindName("cmbProject") as RadComboBox;
               // force the re validation
                var bindingExpression = cmbProject.GetBindingExpression(RadComboBox.SelectedValueProperty);
                bindingExpression.UpdateSource();
            }

    but there are certainly better ways to do this

    Regards,

    Maxence
Back to Top
DevCraft banner