Silverlight TimePicker / ChildWindow / DataTemplate组合导致UI冻结

本文关键字:UI 冻结 DataTemplate TimePicker ChildWindow Silverlight 组合 | 更新日期: 2023-09-27 18:18:23

我正在一个Silverlight项目上工作,使用MVVM,我遇到了一个问题,这个问题只出现在一些相当特定的情况下。我尽量把所有的东西都精简下来,只留下重要的部分。

的场景:

  • 标准Silverlight ChildWindow
  • ChildWindow具有Selector控制(例如ComboBoxListBox)。
  • ChildWindowContentPresenter
    • 这个ContentPresenterContent被绑定到上面提到的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);
      }
    }
}

Silverlight TimePicker / ChildWindow / DataTemplate组合导致UI冻结

我刚刚在SL5中尝试过,无法重现您的问题。如果我有时间,我会尝试SL4。你现在有什么款式可能会造成问题吗?

如果你描述的是一种情况,覆盖出现后解散ChildWindow,那么它是已知的bug。这是一个解决方法。

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