2011-03-15 39 views
1

我正在開發一個使用MVVM的WPF應用程序。在窗口內部,我有一個從UserControl繼承的控件,我們稱其爲DetailView。WPF意外控制卸載

的DetailView被綁定到在VM(CurrentDetail)的性質,可以是不同的類型,UserDetail,AccountDetail,CalendarDetail等,所有的來自同一類繼承

我有一個「ThumbnailBar」我在其中可以已經已經打開的不同的詳細實例之間導航,想象AccountDetail1,AccountDetail2等

此導航的處理更新CurrentDetail在VM和與OnPropertyChanged事件

問題是當我從一種類型切換(例如AccontDetail3)不同的類型(UserDetail6)。我注意到它調用了我要離開的控件的「未加載」事件以及我要初始化的控件,當我通過相同類型的實例導航時,這兩件事都不會發生。

這使我一些問題,如日曆中,我有一個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(的那卸載一個視圖)和是的,我使用過多

<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對每種類型強制卸載,我正在使用的DataTemplates的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> 

這裏AccountView提取物,使得意識,解決這個問題的任何想法?

編輯 - 我有DataTemplates.xaml與DataTemplate中爲每種類型的的ResourceDictionary,例如:

<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

+1

請提供更多信息:「在詳細實例之間導航」究竟意味着什麼? – Jon 2011-03-15 11:01:56

+0

如果您使用的是MVVM,並使用雙向綁定將調度程序的日期綁定到ViewModel,那麼即使控件被卸載並重新創建,我也會期望它保持該值。你在使用MVVM嗎? – 2011-03-15 11:44:21

+0

是的,我正在使用MVVM,抱歉不說。我可以使用這種方法的事情是不想控制卸載,這是可能的嗎? – Juan 2011-03-15 11:52:05

回答

1

如果你想爲了讓itemdetails保持狀態,您應該將狀態置於用於顯示itemdetails的UserControl之外的其他位置。

當加載不同的類型和相應的用戶控件時,usercontrol(以及它的狀態)被卸載是非常正常的。

所以你建議的補丁或多或少是一個正確的解決方案。

+0

感謝您的回答。所以,只有當它們改變類型時才能卸載是正常的行爲(但是繼承自繼承自UserControl的相同子類),加載具有相同類型的不同控件(實例)不會卸載...? – Juan 2011-03-15 11:45:11

+0

我不知道這個實現,但是當所有會改變的內容都是綁定到控件的內容時,我不再重新創建相同的控件似乎是合理的。 – 2011-03-15 14:01:43

+0

現在有任何幫助與新的信息?謝謝 – Juan 2011-03-16 15:33:07