2011-12-21 37 views
0

我正在使用MVVM开发一个Silverlight项目,而且我遇到了一个问题,它只出现在一些相当特定的情况下。我试图尽可能地去除一切,只留下重要的部分。Silverlight TimePicker/ChildWindow/DataTemplate组合导致UI冻结

的方案:

  • 一个标准的Silverlight ChildWindow
  • ChildWindow具有Selector控制(例如ComboBoxListBox)。
  • ChildWindow具有ContentPresenter
    • ContentPresenterContent势必的上述SelectedValue提到Selector控制(在现实中,它被绑定到一个ViewModel属性,但出于测试目的,这是不必要的)。
    • ContentPresenter使用DataTemplateSelector,以确定它的ContentTemplate
  • Selector控制包含string值 “A” 和 “B” 对应于DataTemplate的 “TemplateA” 和 “TemplateB”。
  • “TemplateB”包含一个TimePicker控件。

问题:

选择“B”后(因此加载“TemplateB”),接下来你试图改变所选模板时,主机网页将冻结。没有例外,也没有提供任何信息。

注:

  • 一切工作的ChildWindow的罚款之外。
  • 如果没有模板包含TimePicker控件,则一切正常。
  • 如果在不使用ContentPresenter/DataTemplateSelector的情况下显示,则TimePicker控件看起来工作正常。
  • 我在Silverlight Toolkit CodePlex页面上查看了TimePicker in ChildWindow causes an exception。这个特殊的问题似乎已经解决了,我试图执行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> 

视图模型:

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

您是否尝试过附加一个调试器,中断执行并分析线程上的调用堆栈(特别是主线程)?他们是否干净,或者有些人正处于睡眠,等待或加入状态? – 2011-12-23 19:27:15

回答

0

我刚刚在SL5中尝试过,并且无法重现您的问题。如果我有时间,我会尝试SL4。你有任何可能导致问题的风格吗?

如果您描述的是解除ChildWindow后出现重叠的情况,那么它是已知的错误。这是一个解决方法。

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

感谢您的回复,但是这似乎没有任何影响。挂起发生在窗口关闭事件被触发之前。 – wdavo 2011-12-28 07:32:04