This is a migrated thread and some comments may be shown as answers.

Difficulties updating view

2 Answers 126 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Oscar Wahlen
Top achievements
Rank 1
Oscar Wahlen asked on 22 Jul 2011, 01:29 PM

In this example I have two custom properties (IsBusy and IsFree). I want to update IsFree whenever IsBusy is changed and notify the view. But for some reason the view is not updated until after I have saved and closed the appointment. How can I update the view before the changes are saved?

MainPageViewModel.cs

using System; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
    
namespace SampleProject 
    using System.Collections.ObjectModel; 
    
    using Telerik.Windows.Controls.ScheduleView; 
    
    public class MainPageViewModel 
    
        private ObservableCollection<Task> appointments; 
    
        public MainPageViewModel() 
        
            this.appointments = new ObservableCollection<Task>(); 
        
    
        public ObservableCollection<Task> Appointments 
        
            get { return this.appointments; } 
        
    
}

Task.cs (custom appointment)

using System; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
    
namespace SampleProject 
    using Telerik.Windows.Controls.ScheduleView; 
    
    public class Task : Appointment 
    
        private bool isDone; 
    
        private bool isFree; 
    
        public bool IsDone 
        
            get { return this.Storage<Task>().isDone; } 
            set
            
                this.Storage<Task>().isDone = value; 
                this.Storage<Task>().IsFree = value; 
                base.OnPropertyChanged(() => this.IsDone); 
            
        
    
        public bool IsFree 
        
            get { return this.Storage<Task>().isFree; } 
            set
            
                this.Storage<Task>().isFree = value; 
                base.OnPropertyChanged(() => this.IsFree); 
            
        
    
        public override IAppointment Copy() 
        
            IAppointment _newTask = new Task(); 
            _newTask.CopyFrom(this); 
            return _newTask; 
        
    
        public override void CopyFrom(IAppointment other) 
        
            Task _theTask = other as Task; 
            if (_theTask != null
            
                this.IsDone = _theTask.IsDone; 
                this.IsFree = _theTask.IsFree; 
            
            base.CopyFrom(other); 
        
    
}

MainPage.xaml (View)

<UserControl x:Class="SampleProject.MainPage"
    xmlns:local="clr-namespace:SampleProject"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    <UserControl.Resources
        <local:MainPageViewModel x:Key="MainPageViewModel" /> 
        <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:RadToolBarSeparator/> 
                    <TextBlock x:Name="ShowAs" Foreground="{StaticResource RadScheduleForeground}" Margin="1 0 1 1" telerik:LocalizationManager.ResourceKey="ShowAs" VerticalAlignment="Center"/> 
                    <telerik:RadComboBox x:Name="PART_TimeMarkers" ClearSelectionButtonContent="{Binding ClearSelectionButtonContent}" ClearSelectionButtonVisibility="Visible" EmptyText="{Binding TimeMarkersEmptyText}" ItemTemplate="{StaticResource TimeMarkerComboBoxItemContentTemplate}" ItemsSource="{Binding TimeMarkers}" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Margin="2 1" SelectionBoxTemplate="{StaticResource TimeMarkerComboBoxItemContentTemplate}" SelectedItem="{Binding Occurrence.Appointment.TimeMarker, Mode=TwoWay}" telerik:StyleManager.Theme="{StaticResource Theme}" Width="110"/> 
                    <telerik:RadComboBox x:Name="PART_Categories" ClearSelectionButtonContent="{Binding ClearSelectionButtonContent}" ClearSelectionButtonVisibility="Visible" EmptyText="{Binding CategoriesEmptyText}" ItemTemplate="{StaticResource CategoryComboBoxItemContentTemplate}" ItemsSource="{Binding Categories}" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Margin="2 1" SelectionBoxTemplate="{StaticResource CategoryComboBoxItemContentTemplate}" SelectedItem="{Binding Occurrence.Appointment.Category, Mode=TwoWay}" telerik:StyleManager.Theme="{StaticResource Theme}" Width="120"/> 
                    <telerik:RadToggleButton x:Name="HighImportaceButton" Height="22" IsChecked="{Binding IsHighImportance, Mode=TwoWay}" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Width="22"
                        <ToolTipService.ToolTip
                            <ToolTip telerik:LocalizationManager.ResourceKey="HighImportance" telerik:StyleManager.Theme="{StaticResource Theme}"/> 
                        </ToolTipService.ToolTip
                        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"
                            <Path Data="M200.39647,58.840393 C200.39337,58.336426 201.14566,57.683922 202.56244,57.684292 C204.06589,57.684685 204.73764,58.357765 204.72783,58.992363 C205.04649,61.795574 203.04713,64.181099 202.47388,66.133446 C201.93753,64.154961 199.9471,61.560352 200.39647,58.840393 z" HorizontalAlignment="Center" Height="10" Stretch="Fill" Width="5.451"
                                <Path.Fill
                                    <LinearGradientBrush EndPoint="1.059,0.375" StartPoint="-0.457,0.519"
                                        <GradientStop Color="#FFFF0606" Offset="0.609"/> 
                                        <GradientStop Color="#FFBF0303" Offset="0.927"/> 
                                    </LinearGradientBrush
                                </Path.Fill
                            </Path
                            <Ellipse HorizontalAlignment="Center" Height="3" Width="3"
                                <Ellipse.Fill
                                    <RadialGradientBrush
                                        <GradientStop Color="#FFFF0606" Offset="0"/> 
                                        <GradientStop Color="#FFBF0303" Offset="1"/> 
                                    </RadialGradientBrush
                                </Ellipse.Fill
                            </Ellipse
                        </StackPanel
                    </telerik:RadToggleButton
                    <telerik:RadToggleButton x:Name="LowImportaceButton" Height="22" IsChecked="{Binding IsLowImportance, Mode=TwoWay}" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}" Width="22"
                        <ToolTipService.ToolTip
                            <ToolTip telerik:LocalizationManager.ResourceKey="LowImportance" telerik:StyleManager.Theme="{StaticResource Theme}"/> 
                        </ToolTipService.ToolTip
                        <Path Data="M222.40353,60.139881 L226.65768,60.139843 L226.63687,67.240196 L229.15347,67.240196 L224.37816,71.394943 L219.65274,67.240196 L222.37572,67.219345 z" HorizontalAlignment="Center" Height="12" Stretch="Fill" Stroke="#FF0365A7" VerticalAlignment="Center" Width="9"
                            <Path.Fill
                                <LinearGradientBrush EndPoint="1.059,0.375" StartPoint="-0.457,0.519"
                                    <GradientStop Color="#FFBBE4FF"/> 
                                    <GradientStop Color="#FF024572" Offset="0.836"/> 
                                    <GradientStop Color="#FF43ADF4" Offset="0.466"/> 
                                </LinearGradientBrush
                            </Path.Fill
                        </Path
                    </telerik:RadToggleButton
                </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="120"/> 
                        <ColumnDefinition Width="*"/> 
                        <ColumnDefinition Width="*"/> 
                    </Grid.ColumnDefinitions
                    <Grid.RowDefinitions
                        <RowDefinition Height="Auto"/> 
                        <RowDefinition Height="*"/> 
                        <RowDefinition Height="Auto"/> 
                        <RowDefinition Height="Auto"/> 
                        <RowDefinition /> 
                    </Grid.RowDefinitions
                    <TextBlock Grid.Column="0" Margin="6" Grid.Row="0" telerik:LocalizationManager.ResourceKey="Subject"/> 
                    <TextBox Grid.ColumnSpan="2" Grid.Column="1" IsReadOnly="{Binding IsReadOnly}" Margin="3" Grid.Row="0" Text="{Binding Occurrence.Appointment.Subject, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" telerik:StyleManager.Theme="{StaticResource Theme}"/> 
                    <TextBlock Grid.Column="0" Margin="6" Grid.Row="1" telerik:LocalizationManager.ResourceKey="Body"/> 
                    <TextBox Grid.ColumnSpan="2" Grid.Column="1" Height="70" IsReadOnly="{Binding IsReadOnly}" Margin="3" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Occurrence.Appointment.Body, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" telerik:StyleManager.Theme="{StaticResource Theme}" VerticalScrollBarVisibility="Visible" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"/> 
                    <TextBlock Grid.Column="0" Margin="6" Grid.Row="2" telerik:LocalizationManager.ResourceKey="StartTime"/> 
                    <telerik:RadDateTimePicker Culture="{Binding DefaultCulture, Source={StaticResource LocalizationManager}}" Grid.Column="1" IsReadOnly="{Binding IsReadOnly}" IsEnabled="{Binding IsNotRecurrent}" Margin="3" Grid.Row="2" 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.Column="0" Margin="6" Grid.Row="3" telerik:LocalizationManager.ResourceKey="EndTime" telerik:StyleManager.Theme="{StaticResource Theme}" VerticalAlignment="Center"/> 
                    <StackPanel Grid.Row="4"
                        <CheckBox Margin="3" Content="Is done?" IsChecked="{Binding Occurrence.Appointment.IsDone, Mode=TwoWay}"/> 
                        <CheckBox Margin="3" Content="Is free?" IsChecked="{Binding Occurrence.Appointment.IsFree, Mode=TwoWay}"/> 
                    </StackPanel
                    <telerik:RadDateTimePicker Culture="{Binding DefaultCulture, Source={StaticResource LocalizationManager}}" Grid.Column="1" IsReadOnly="{Binding IsReadOnly}" IsEnabled="{Binding IsNotRecurrent}" Margin="3" Grid.Row="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
                </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
        <Style x:Key="EditAppointmentDialogStyle" TargetType="telerik:SchedulerDialog"
            <Setter Property="Foreground" Value="{StaticResource RadScheduleForeground}"/> 
            <Setter Property="Width" Value="560"/> 
            <Setter Property="IsTabStop" Value="False"/> 
            <Setter Property="Template" Value="{StaticResource EditAppointmentTemplate}"/> 
            <Setter Property="HeaderTemplate"
                <Setter.Value
                    <DataTemplate
                        <StackPanel HorizontalAlignment="Left" MaxWidth="400" Orientation="Horizontal"
                            <TextBlock telerik:LocalizationManager.ResourceKey="Event" Visibility="{Binding Occurrence.Appointment.IsAllDayEvent, Converter={StaticResource BooleanToVisibilityConverter}}"/> 
                            <TextBlock telerik:LocalizationManager.ResourceKey="Appointment" Visibility="{Binding Occurrence.Appointment.IsAllDayEvent, Converter={StaticResource InvertedBooleanToVisibilityConverter}}"/> 
                            <TextBlock Text=" - "/> 
                            <TextBlock x:Name="SubjectTextBlock" Text="{Binding Occurrence.Appointment.Subject}" Visibility="{Binding Occurrence.Appointment.Subject, Converter={StaticResource NullToVisibilityConverter}}"/> 
                            <TextBlock telerik:LocalizationManager.ResourceKey="Untitled" Visibility="{Binding Occurrence.Appointment.Subject, Converter={StaticResource InvertedNullToVisibilityConverter}}"/> 
                        </StackPanel
                    </DataTemplate
                </Setter.Value
            </Setter
            <Setter Property="IconTemplate"
                <Setter.Value
                    <DataTemplate
                        <Image Source="/Telerik.Windows.Controls.ScheduleView;component/Themes/Images/EditAppointment.png" Stretch="None"/> 
                    </DataTemplate
                </Setter.Value
            </Setter
        </Style
        <Style x:Key="RadScheduleViewStyle1" TargetType="telerik:RadScheduleView"
            <Setter Property="EditAppointmentDialogStyle" Value="{StaticResource EditAppointmentDialogStyle}"/> 
        </Style
    </UserControl.Resources
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource MainPageViewModel}"
        <telerik:RadScheduleView AppointmentsSource="{Binding Appointments}" Style="{StaticResource RadScheduleViewStyle1}"
            <telerik:RadScheduleView.ViewDefinitions
                <telerik:DayViewDefinition /> 
                <telerik:MonthViewDefinition /> 
            </telerik:RadScheduleView.ViewDefinitions
        </telerik:RadScheduleView
    </Grid
</UserControl>

2 Answers, 1 is accepted

Sort by
0
Valeri Hristov
Telerik team
answered on 22 Jul 2011, 04:09 PM
Hi Oscar,

We intentionally update the view only after the user confirms the changes because they might affect the grouping, which could cause the control to reset its UI, which is a potential performance problem. I generally would not recommend changing this behavior, but if you really need to update the ScheduleView when an appointment property changes, you could implement the property using the regular pattern, e.g. without using the Storage() method, but a simple member variable. In addition, you should create a new OnPropertyChanged method (with a different name) that should raise the PropertyChanged event, and call it instead of the original. If you implement the logic like this, however, the Cancel button will not be able to revert the changes.

Greetings,
Valeri Hristov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Oscar Wahlen
Top achievements
Rank 1
answered on 27 Jul 2011, 12:34 PM
Hi,

Thank you for your answer. But what is the best supported approach to mimic the "cancel" command? And what is the exact purpose of the Storage collection?

I have my "Cancel" button declared like this:

<Button Width="96" Height="20" Grid.Column="1" HorizontalAlignment="Right" telerik:RadWindow.ResponseButton="Cancel" Content="Cancel">
    <telerik:CommandManager.InputBindings>
        <telerik:InputBindingCollection>
            <telerik:MouseBinding Command="telerik:WindowCommands.Cancel" Gesture="LeftClick" />
        </telerik:InputBindingCollection>
    </telerik:CommandManager.InputBindings>
</Button>

And it does exactly what it did before I implemented the traditional MVVM logic (when I cancel the appointment the changes are not saved). So what is the point of using this "virtual" collection to store my values?
Tags
ScheduleView
Asked by
Oscar Wahlen
Top achievements
Rank 1
Answers by
Valeri Hristov
Telerik team
Oscar Wahlen
Top achievements
Rank 1
Share this question
or