【问题标题】:Silverlight TimePicker / ChildWindow / DataTemplate combination causes UI freezeSilverlight TimePicker / ChildWindow / DataTemplate 组合导致 UI 冻结
【发布时间】:2011-12-21 06:20:52
【问题描述】:

我正在使用 MVVM 处理 Silverlight 项目,但我遇到了一个似乎只在某些相当特定的情况下才会出现的问题。我试图尽可能地精简所有内容,只留下重要的部分。

情景:

  • 标准 Silverlight ChildWindow
  • ChildWindow 具有 Selector 控件(例如 ComboBoxListBox)。
  • ChildWindow 有一个ContentPresenter
    • ContentPresenterContent 绑定到上述Selector 控件的SelectedValue(实际上它绑定到ViewModel 属性,但出于测试目的,这不是必需的)。李>
    • ContentPresenter 使用DataTemplateSelector 来确定它是ContentTemplate
  • Selector 控件包含对应于DataTemplates“模板A”和“模板B”的string 值“A”和“B”。
  • “TemplateB”包含一个TimePicker 控件。

问题:

选择“B”后(因此加载“TemplateB”),下次尝试更改所选模板时,主机网页将冻结。没有抛出异常,也没有给出任何信息。

注意事项:

  • ChildWindow 之外一切正常。
  • 如果没有任何模板包含TimePicker 控件,则一切正常。
  • TimePicker 控件在不使用 ContentPresenter/DataTemplateSelector 的情况下显示时似乎可以正常工作。
  • 我查看了 Silverlight Toolkit CodePlex 页面上的 TimePicker in ChildWindow causes an exception。该特定问题似乎已解决,我已尝试实施 the suggested workaround 以确保它没有任何效果。

重现问题的代码:

ChildWindowXAML:

<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" }; } }

数据模板选择器:

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);
      }
    }
}

【问题讨论】:

  • 您是否尝试过附加调试器、中断执行并分析线程(尤其是主线程)上的调用堆栈?它们是干净的还是有些“处于睡眠、等待或加入”状态?

标签: c# .net silverlight silverlight-4.0 silverlight-toolkit


【解决方案1】:

我刚刚在 SL5 中尝试过,但无法重现您的问题。如果我有时间,我会尝试 SL4。您是否有任何可能导致问题的样式?

如果您描述的是在关闭 ChildWindow 后出现覆盖的情况,那么这是已知的错误。这是一种解决方法。

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

【讨论】:

  • 感谢您的回复,但这似乎没有任何效果。挂起发生在窗口关闭事件被触发之前。
猜你喜欢
  • 2012-08-02
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2015-03-28
  • 2018-08-12
  • 1970-01-01
相关资源
最近更新 更多