This question is locked. New answers and comments are not allowed.
I'm using a custom appointment class. In addition to showing the "Subject" for the Appointment on the ScheduleView, I'd like to optionally add a RadButton that displays/hides based on data in my CustomAppointmentItem class (See circled button on attached jpg).
In my case, the customer wants to have a button displayed based on the data in the CustomAppointmentItem. Clicking this button would bring them to another screen in the application (instead of opening the Appointment detail window). Double clicking the Appointment subject should open the custom detail window to edit the appointment - as usual.
This is what I tried:
XAML...
<Grid x:Name="MouseOverOverlay" Visibility="Collapsed" Opacity="0">
<telerik:RadButton x:Name="LaunchButton" Width="11" Height="11" Margin="5 5 6 5" Padding="0"
HorizontalAlignment="Right" VerticalAlignment="Top"
Command="{Binding LaunchCommand, Source={StaticResource Model}}" ClickMode="Press"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}}"
IsTabStop="False" Content="^"
telerik:StyleManager.Theme="{StaticResource Theme}">
<ToolTipService.ToolTip>
<TextBlock Text="Launch the Task associated with this Item" telerik:StyleManager.Theme="{StaticResource Theme}"/>
</ToolTipService.ToolTip>
</telerik:RadButton>
</Grid>
ViewModel...
public ICommand LaunchCommand ... CanLaunch / Launch
private CustomAppointmentItem ConvertAppointmentItem(object parameter)
{
if (parameter == null)
return null;
AppointmentItem ai = parameter as AppointmentItem;
if (ai == null)
return null;
CustomAppointmentItem cai = ai.Appointment as CustomAppointmentItem;
return cai;
}
private bool CanLaunch(object parameter)
{
CustomAppointmentItem cai = ConvertAppointmentItem(parameter);
if (cai == null)
return false;
if (cai.IsLaunchButtonEnabled)
return true; // Launch Button should be visible
return false;
}
public void Launch(object parameter)
{
CustomAppointmentItem cai = ConvertAppointmentItem(parameter);
if (cai != null)
{
// launch code here...
}
}
It works... but not consistently. I think I understand why it doesn't work. It's b/c the command is bound to the ViewModel instead of an instance of my CustomAppointmentItem. By passing the CustomAppointmentItem instance as a CommandParameter (instead of binding to it directly), the PropertyChanged event is not firing properly. As I move back/forth through the ScheduleView the RadButton display gets out-of-sync with CustomAppointmentItem instance represented in the AppointmentItem. The button displays when it shouldn't and doesn't display when it should. Invoking the OnCanExecuteChanged on the command when the Appointment data changes doesn't work.
Ideally what I'd like to do is bind the Command (in the MouseOverOverlay Button) directly to my CustomAppointmentItem class (instead of the AppointmentItem via TemplatedParent... or passing it via a CommandParameter). Is this possible?
Another approach I tried was to modify the AppointmentItemTemplate DataTemplate... but I have the same problem b/c I'm not able to bind to the custom appointment property ("CustomProperty" in the code below).
<DataTemplate x:Key="FPIAppointmentItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Subject}" TextWrapping="Wrap" TextTrimming="WordEllipsis" dragDrop:DragDropManager.AllowDrag="False" />
<TextBlock Text="{Binding CustomProperty}" TextWrapping="Wrap" TextTrimming="WordEllipsis" dragDrop:DragDropManager.AllowDrag="False" />
</StackPanel>
</DataTemplate>
Any thoughts?
Thanks,
Paul
In my case, the customer wants to have a button displayed based on the data in the CustomAppointmentItem. Clicking this button would bring them to another screen in the application (instead of opening the Appointment detail window). Double clicking the Appointment subject should open the custom detail window to edit the appointment - as usual.
This is what I tried:
- Add a RadButton to the MouseOverOverlay (within the AppointmentItemVerticalControlTemplate/AppointmentItemHorizontalControlTemplate)
- Bind the Command of the button to the ViewModal and passing the TemplatedParent as a CommandParameter
- Inside the ViewModel Command's Execute/CanExecute methods I cast the Parameter to an "AppointmentItem"... then cast it's "Appointment" property to my CustomAppointmentItem.
- Evaluate properties on CustomAppointmentItem that tell me if the button should be visible -and- what to do if the button is clicked.
XAML...
<Grid x:Name="MouseOverOverlay" Visibility="Collapsed" Opacity="0">
<telerik:RadButton x:Name="LaunchButton" Width="11" Height="11" Margin="5 5 6 5" Padding="0"
HorizontalAlignment="Right" VerticalAlignment="Top"
Command="{Binding LaunchCommand, Source={StaticResource Model}}" ClickMode="Press"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}}"
IsTabStop="False" Content="^"
telerik:StyleManager.Theme="{StaticResource Theme}">
<ToolTipService.ToolTip>
<TextBlock Text="Launch the Task associated with this Item" telerik:StyleManager.Theme="{StaticResource Theme}"/>
</ToolTipService.ToolTip>
</telerik:RadButton>
</Grid>
ViewModel...
public ICommand LaunchCommand ... CanLaunch / Launch
private CustomAppointmentItem ConvertAppointmentItem(object parameter)
{
if (parameter == null)
return null;
AppointmentItem ai = parameter as AppointmentItem;
if (ai == null)
return null;
CustomAppointmentItem cai = ai.Appointment as CustomAppointmentItem;
return cai;
}
private bool CanLaunch(object parameter)
{
CustomAppointmentItem cai = ConvertAppointmentItem(parameter);
if (cai == null)
return false;
if (cai.IsLaunchButtonEnabled)
return true; // Launch Button should be visible
return false;
}
public void Launch(object parameter)
{
CustomAppointmentItem cai = ConvertAppointmentItem(parameter);
if (cai != null)
{
// launch code here...
}
}
It works... but not consistently. I think I understand why it doesn't work. It's b/c the command is bound to the ViewModel instead of an instance of my CustomAppointmentItem. By passing the CustomAppointmentItem instance as a CommandParameter (instead of binding to it directly), the PropertyChanged event is not firing properly. As I move back/forth through the ScheduleView the RadButton display gets out-of-sync with CustomAppointmentItem instance represented in the AppointmentItem. The button displays when it shouldn't and doesn't display when it should. Invoking the OnCanExecuteChanged on the command when the Appointment data changes doesn't work.
Ideally what I'd like to do is bind the Command (in the MouseOverOverlay Button) directly to my CustomAppointmentItem class (instead of the AppointmentItem via TemplatedParent... or passing it via a CommandParameter). Is this possible?
Another approach I tried was to modify the AppointmentItemTemplate DataTemplate... but I have the same problem b/c I'm not able to bind to the custom appointment property ("CustomProperty" in the code below).
<DataTemplate x:Key="FPIAppointmentItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Subject}" TextWrapping="Wrap" TextTrimming="WordEllipsis" dragDrop:DragDropManager.AllowDrag="False" />
<TextBlock Text="{Binding CustomProperty}" TextWrapping="Wrap" TextTrimming="WordEllipsis" dragDrop:DragDropManager.AllowDrag="False" />
</StackPanel>
</DataTemplate>
Any thoughts?
Thanks,
Paul