我正在使用MVVM开发一个Silverlight项目,而且我遇到了一个问题,它只出现在一些相当特定的情况下。我试图尽可能地去除一切,只留下重要的部分。Silverlight TimePicker/ChildWindow/DataTemplate组合导致UI冻结
的方案:
- 一个标准的Silverlight
ChildWindow
- 的
ChildWindow
具有Selector
控制(例如ComboBox
或ListBox
)。 - 的
ChildWindow
具有ContentPresenter
- 此
ContentPresenter
的Content
势必的上述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);
}
}
}
您是否尝试过附加一个调试器,中断执行并分析线程上的调用堆栈(特别是主线程)?他们是否干净,或者有些人正处于睡眠,等待或加入状态? – 2011-12-23 19:27:15