2011-12-21 3 views
0

Я работаю над проектом Silverlight, используя MVVM, и у меня возникла проблема, которая появляется только в некоторых довольно специфических ситуациях. Я попытался как можно больше убрать все, чтобы остались только важные части.Silverlight TimePicker/ChildWindow/DataTemplate вызывает зависание UI

Сценарий:

  • стандартном Silverlight ChildWindow
  • The ChildWindow имеет Selector управления (например, ComboBox или ListBox).
  • ChildWindow имеет ContentPresenter
    • Content этого ContentPresenter привязанный к SelectedValue из выше Selector управления (В действительности это связано со свойством ViewModel, но для целей тестирования это не обязательно).
    • ContentPresenter использует DataTemplateSelector для определения его ContentTemplate
  • Selector управления содержит string значения "A" и "B", которые соответствуют DataTemplate S "TemplateA" и "TemplateB".
  • "TemplateB" содержит элемент управления TimePicker.

Проблема:

После выбора «B» (поэтому загрузка «TemplateB»), в следующий раз, когда вы пытаетесь изменить выбранный шаблон, хозяин веб-страница будет замерзать. Никакое исключение не выбрасывается и информация не предоставляется.

Примечания:

  • Все отлично работает за пределами ChildWindow.
  • Все работает нормально, если ни один из шаблонов не содержит элемент управления TimePicker.
  • Управление TimePicker работает нормально, если оно отображается без использования ContentPresenter/DataTemplateSelector.
  • Ive посмотрел на TimePicker in ChildWindow causes an exception на странице CodeLlex инструментальных средств Silverlight. Эта конкретная проблема, похоже, решена, и я попытался реализовать the suggested workaround, чтобы быть уверенным, и это не имеет никакого эффекта.

код, чтобы воспроизвести проблему:

ChildWindow XAML:

<controls:ChildWindow 
x:Class="TimePickerProblem.ChildWindow1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" 
xmlns:local="clr-namespace:TimePickerProblem" 
Width="400" 
Height="300" 
Title="ChildWindow1"> 
<controls:ChildWindow.Resources> 
    <local:ViewModel 
     x:Key="vm" /> 
</controls:ChildWindow.Resources> 
<Grid> 
    <Grid 
     x:Name="LayoutRoot" 
     Background="White" 
     DataContext="{StaticResource vm}"> 
     <StackPanel 
      HorizontalAlignment="Center"> 
      <ComboBox 
       x:Name="ComboBox" 
       Margin="20" 
       ItemsSource="{Binding Templates}" /> 
      <ContentPresenter 
       Content="{Binding ElementName=ComboBox, Path=SelectedValue}"> 
       <ContentPresenter.ContentTemplate> 
        <DataTemplate> 
         <local:TemplateSelector 
          Content="{Binding}"> 
          <local:TemplateSelector.TemplateA> 
           <DataTemplate> 
            <TextBlock 
             Text="Hello from A" /> 
           </DataTemplate> 
          </local:TemplateSelector.TemplateA> 
          <local:TemplateSelector.TemplateB> 
           <DataTemplate> 
            <toolkit:TimePicker /> 
           </DataTemplate> 
          </local:TemplateSelector.TemplateB> 
         </local:TemplateSelector> 
        </DataTemplate> 
       </ContentPresenter.ContentTemplate> 
      </ContentPresenter> 
     </StackPanel> 
    </Grid> 
    <Button 
     x:Name="CancelButton" 
     Content="Cancel" 
     Click="CancelButton_Click" 
     Width="75" 
     Height="23" 
     HorizontalAlignment="Right" 
     Margin="0,12,0,0" 
     Grid.Row="1" /> 
    <Button 
     x:Name="OKButton" 
     Content="OK" 
     Click="OKButton_Click" 
     Width="75" 
     Height="23" 
     HorizontalAlignment="Right" 
     Margin="0,12,79,0" 
     Grid.Row="1" /> 
</Grid> 

ViewModel:

public List<string> Templates { get { return new List<string>() { "a", "b" }; } } 

DataTemplateSelector:

public class TemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate TemplateA { get; set; } 
    public DataTemplate TemplateB { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     string value = (string)item; 

     switch (value.ToLower()) 
     { 
     case "a": 
      return TemplateA; 
     case "b": 
      return TemplateB; 
     default: 
      return base.SelectTemplate(item, container); 
     } 
    } 
} 
+0

Вы пытались установить отладчик, нарушая выполнение и анализируя стеки вызовов в потоках (особенно в главной теме)? Являются ли они чистыми или, может быть, некоторые из них «находятся в состоянии сна, ждут или присоединяются»? –

ответ

0

Я только что попытался в SL5 и не смог воспроизвести вашу проблему. Если у меня будет время, я попробую SL4. Есть ли у вас какие-либо стили, которые могут вызвать проблемы?

Если вы описываете ситуацию, когда после отклонения ChildWindow появляется оверлей, тогда это известная ошибка. Вот обходной путь.

ChildWindow w = new MyChildWindow(); 
w.Closed += (s, eargs) => { Application.Current.RootVisual.SetValue(Control.IsEnabledProperty, true); }; 
w.Show(); 
+0

Спасибо за ответ, однако это, похоже, не имеет никакого эффекта. Повреждение происходит до того, как событие закрытия окна будет запущено. – wdavo