我正在使用MVVM开发WPF应用程序。在Window中,我有一个继承自UserControl的控件,我们称之为DetailView。
DetailView绑定到VM(CurrentDetail)中的属性,可以是不同类型的属性,UserDetail,AccountDetail,CalendarDetail等。所有都继承自同一个类
我有一个“ThumbnailBar”,我可以在其中导航已经打开的不同详细信息实例,想象一下AccountDetail1,AccountDetail2等。
处理此导航以更新VM中的CurrentDetail并使用OnPropertyChanged事件
当我从一种类型(例如AccontDetail3)切换到另一种不同类型(UserDetail6)时出现问题。我注意到它调用了我正在离开的控件的“Unloaded”事件,我要进行的控件是Initialized,当我浏览相同类型的实例时,这两件事都没有发生
这会给我带来一些问题,例如日历里我有一个telerik RadScheduler,它不会保存我导航到的日期,并在今天的日期重新加载。
我知道并且我已经测试过,我可以保存变量SelectecTimeSlot并继续重新加载它,但那只是一个补丁
编辑 - 一些代码:
这是MainView.xaml,我在其中调用 CurrentDetailsWorkSpace
<Border x:Name="BorderExteriorContent" BorderBrush="Transparent" BorderThickness="0"
Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2">
<ContentControl
x:Name="DetalleContenidoWrkSpc"
Background="Red"
Height="{Binding ElementName=BorderExteriorContent,Path=ActualHeight}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Content="{Binding CurrentDetailsWorkSpace}"
VerticalAlignment="Top" Panel.ZIndex="1" />
</Border>
这是 CalendarView (其中一个卸载的视图)和是我正在使用DataTemplates
<base:BaseUCView
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:base="clr-namespace:MRWTINT.HGC.Win.Views.Base"
mc:Ignorable="d"
xmlns:calVm="clr-namespace:MRWTINT.HGC.Win.ViewModels.Calendario"
x:Class="MRWTINT.HGC.Win.Views.Calendario.CalendarioView"
xmlns:draganddrop="clr-namespace:MRWTINT.HGC.Win.ViewModels.DragDropLib"
xmlns:Calendario="clr-namespace:MRWTINT.HGC.Win.Themes.Calendario"
Margin="0"
d:DesignWidth="730" Height="Auto"
Unloaded="BaseUcViewUnloaded">
<Border x:Name="border" Margin="0,0,30,0" BorderBrush="#FF8A8A8A" BorderThickness="1" CornerRadius="3" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Grid >
<Grid Background="White" Grid.IsSharedSizeScope="True">
<Grid.Resources>
<DataTemplate x:Key="DayWeekSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="20" MinWidth="800" />
</DataTemplate>
<DataTemplate x:Key="AllDaySlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="44" MinWidth="800" />
</DataTemplate>
<DataTemplate x:Key="MonthSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="120" MinWidth="120" />
</DataTemplate>
<DataTemplate x:Key="TimeLineSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="800" MinWidth="110" />
</DataTemplate>
<Calendario:TimeSlotTemplateSelector
x:Key="TimeSlotTemplateSelector"
MonthSlotTemplate="{StaticResource MonthSlotTemplate}"
TimeLineSlotTemplate="{StaticResource TimeLineSlotTemplate}"
AllDaySlotTemplate="{StaticResource AllDaySlotTemplate}"
DayWeekSlotTemplate="{StaticResource DayWeekSlotTemplate}"
/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="busyIndicator"
Grid.Row="1" BusyContent="{DynamicResource LBL_DetalleCalendario}"
IsBusy="{Binding IsBusy}" Background="{x:Null}" BorderBrush="{x:Null}"
DisplayAfter="{Binding BusyIndicatorDelayedDisplay}">
<telerik:RadScheduler x:Name="scheduler"
TimeSlotTemplateSelector="{StaticResource TimeSlotTemplateSelector}"
draganddrop:DragDropHelper.IsDropTarget="true"
Margin="0"
Grid.Row="1"
FirstDayOfWeek="Monday" FontFamily="Arial" FontSize="10.667"
AppointmentsSource="{Binding ActividadesView}"
calVm:CalendarioEventBehaviours.CalendarioCreateActividadCommand="{Binding SaveCommand}"
calVm:CalendarioEventBehaviours.CalendarioAddActividadCommand="{Binding AddNewActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioDeleteActividadCommand="{Binding DeleteActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioEditingActividadCommand="{Binding EditingActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioEditedActividadCommand="{Binding EditedActividadCommand}"
telerik:StyleManager.Theme="{DynamicResource RadSchedulerTheme}"
ToolTip="{DynamicResource LBL_ToolTip_Calendario_Generico}"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
ShowsConfirmationWindowOnDelete="False"
OpenModalDialogs="True" Height="Auto"
AllDayAreaHeight="0"
ViewMode="{Binding CalendarioViewMode, Mode=OneWayToSource}">
<telerik:RadScheduler.MonthViewDefinition >
<telerik:MonthViewDefinition />
</telerik:RadScheduler.MonthViewDefinition>
<telerik:RadScheduler.DayViewDefinition >
<telerik:DayViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.DayViewDefinition >
<telerik:RadScheduler.TimelineViewDefinition >
<telerik:TimelineViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.TimelineViewDefinition>
<telerik:RadScheduler.RenderTransform >
<TransformGroup >
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</telerik:RadScheduler.RenderTransform>
<telerik:RadScheduler.WeekViewDefinition >
<telerik:WeekViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.WeekViewDefinition>
<VisualStateManager.CustomVisualStateManager>
<VisualStateManager />
</VisualStateManager.CustomVisualStateManager>
</telerik:RadScheduler>
</telerik:RadBusyIndicator>
<!-- BOTONES PARTE SUPERIOR CALENDARIO -->
<Grid x:Name="Botonera" Margin="10,4,0,0" RenderTransformOrigin="0.5,0.5" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- REFRESCAR CALENDARIO -->
<StackPanel Grid.Column="0" x:Name="PanelRefresh" Orientation="Horizontal" Cursor="Hand">
<Image x:Name="imgResfresh"
Width="16" Height="16" Source="..\..\Resources\Calendario\table_refresh.png" />
<Button x:Name="btnRefresh"
Content="{DynamicResource BTN_Refrescar}"
Style="{StaticResource ButtonStyle}"
Background="{x:Null}" FontFamily="Arial"
FontSize="10.667" Margin="0,0,5,0"
Command="{Binding RefreshCommand}" />
<Image x:Name="imgWeekends" Margin="10,0,0,0"
Width="16" Height="16" Source="..\..\Resources\Calendario\table_row_delete.png" />
<Button x:Name="btnWeekends"
Style="{StaticResource ButtonStyle}"
Background="{x:Null}" FontFamily="Arial"
FontSize="10.667" Margin="0,0,5,0"
Command="{Binding RefreshCommand}" />
</StackPanel>
<!-- /REFRESCAR CALENDARIO -->
</Grid>
<!-- /BOTONES PARTE SUPERIOR CALENDARIO -->
</Grid>
</Grid>
</Border>
这里是我正在使用DataTemplates的AccountView的摘录
<DataTemplate x:Key="ImgContactoTemplate">
<Image RenderOptions.BitmapScalingMode="NearestNeighbor"
Width="16" Height="16" Margin="0,1,0,0" Source="pack://application:,,,/Resources/Cuentas/user.png" />
</DataTemplate>
<DataTemplate x:Key="ImgOportunidadTemplate">
<Image x:Name="imgTipoOportunidadEtapa"
Width="16" Height="16"
RenderOptions.BitmapScalingMode="NearestNeighbor"
Source="{Binding IDTipoEtapa, Converter={StaticResource valueToImageConverter}, ConverterParameter=EtapaOportunidadMini}"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="BtCellDataTemplate">
<Button x:Name="btnNewActivityFromOportunidad" Margin="0" Width="20" Height="20" Background="Transparent" Cursor="Hand"
Command="Cuentas:CuentaViewModel.NewActivityFromOportunidadCommand"
CommandParameter="{Binding IDOportunidad}" Padding="0"
VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="{Binding CanUserCreateNew}"
Style="{DynamicResource ButtonStyle}">
<Image RenderOptions.BitmapScalingMode="NearestNeighbor" Width="16" Height="16"
Margin="0" Source="pack://application:,,,/Resources/Calendario/calendar_add.png" />
</Button>
</DataTemplate>
因此,为每种类型使用不同的DataTemplates都会强制卸载,这是否有意义,任何解决问题的想法?
编辑 - 对于 ResourceDictionary 中的每种类型,我都有DataTemplates.xaml和DataTemplate,例如:
<DataTemplate DataType="{x:Type vmCal:CalendarioBusquedaViewModel}">
<viewsCalendario:CalendarioBusquedaView Width="Auto" MaxWidth="Infinity"/>
</DataTemplate>
相关帖子我已经读过: In wpf, is there a way to execute code before the control is unloaded...? like maybe an unloading event? How to preserve control state within tab items in a TabControl
答案 0 :(得分:1)
如果要在itemdetails中保持状态,则应将状态置于除用于显示itemdetails的UserControl之外的其他位置。
当加载不同类型和相应的用户控件时,卸载usercontrol(及其状态)是很正常的。
因此,您建议的补丁或多或少是正确的解决方案。