Silverlight TimePicker / ChildWindow / DataTemplate组合导致UI冻结
本文关键字:UI 冻结 DataTemplate TimePicker ChildWindow Silverlight 组合 | 更新日期: 2023-09-27 18:18:23
我正在一个Silverlight项目上工作,使用MVVM,我遇到了一个问题,这个问题只出现在一些相当特定的情况下。我尽量把所有的东西都精简下来,只留下重要的部分。
的场景:
- 标准Silverlight
ChildWindow
-
ChildWindow
具有Selector
控制(例如ComboBox
或ListBox
)。 -
ChildWindow
有ContentPresenter
- 这个
ContentPresenter
的Content
被绑定到上面提到的Selector
控件的SelectedValue
(实际上它被绑定到一个ViewModel属性,但为了测试目的,这是不必要的)。 -
ContentPresenter
使用DataTemplateSelector来确定它是ContentTemplate
- 这个
-
Selector
控件包含string
值"A"answers"B",对应DataTemplate
的"TemplateA"answers"TemplateB"。 - "TemplateB"包含一个
TimePicker
控件。
问题:
选择"B"(因此加载"TemplateB")后,下次尝试更改所选模板时,主机网页将冻结。不抛出异常,也不给出任何信息。
指出:
- 在
ChildWindow
之外一切正常。 - 如果没有模板包含
TimePicker
控件,一切都可以正常工作。 - 如果不使用
ContentPresenter
/DataTemplateSelector
显示TimePicker
控件,则CC_20控件似乎可以正常工作。 - 我查看了ChildWindow中的TimePicker导致Silverlight Toolkit CodePlex页面出现异常。这个特定的问题似乎已经解决了,我已经尝试实施建议的解决方案,只是为了确定,它没有效果。
重现问题的代码:
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);
}
}
}
我刚刚在SL5中尝试过,无法重现您的问题。如果我有时间,我会尝试SL4。你现在有什么款式可能会造成问题吗?
如果你描述的是一种情况,覆盖出现后解散ChildWindow,那么它是已知的bug。这是一个解决方法。
ChildWindow w = new MyChildWindow();
w.Closed += (s, eargs) => { Application.Current.RootVisual.SetValue(Control.IsEnabledProperty, true); };
w.Show();