Сочетание Silverlight TimePicker / ChildWindow / DataTemplate вызывает зависание пользовательского интерфейса - PullRequest
0 голосов
/ 21 декабря 2011

Я работаю над проектом Silverlight, используя MVVM, и столкнулся с проблемой, которая возникает только в некоторых довольно специфических ситуациях. Я постарался максимально сократить все, чтобы остались только важные части.

Сценарий:

  • Стандартный Silverlight ChildWindow
  • ChildWindow имеет элемент управления Selector (например, ComboBox или ListBox).
  • ChildWindow имеет ContentPresenter
    • Content этого ContentPresenter связан с SelectedValue вышеупомянутого Selector элемента управления (На самом деле он связан со свойством ViewModel, но для целей тестирования это не обязательно).
    • ContentPresenter использует DataTemplateSelector , чтобы определить, ContentTemplate
  • Элемент управления Selector содержит string значения «A» и «B», которые соответствуют DataTemplate s «TemplateA» и «TemplateB».
  • «TemplateB» содержит элемент управления TimePicker.

Проблема:

После выбора «B» (следовательно, загрузки «TemplateB») при следующей попытке изменить выбранный шаблон веб-страница хоста замерзнет. Не выдается никаких исключений и никакой информации не предоставляется.

Примечания:

  • Все отлично работает за пределами ChildWindow.
  • Все работает нормально, если ни один из шаблонов не содержит элемент управления TimePicker.
  • Элемент управления TimePicker работает нормально, если отображается без использования ContentPresenter / DataTemplateSelector.
  • Я посмотрел на TimePicker в ChildWindow вызывает исключение на странице CodePlex набора инструментов Silverlight. Эта конкретная проблема, похоже, решена, и я попытался внедрить предложенный обходной путь , просто чтобы быть уверенным, и он не имеет никакого эффекта.

Код для воспроизведения проблемы:

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>

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

1 Ответ

0 голосов
/ 27 декабря 2011

Я только что попробовал в SL5 и не смог воспроизвести вашу проблему.Если у меня будет время, я попробую SL4.Есть ли у вас какие-либо стили, которые могут вызвать проблему?

Если вы описываете ситуацию, когда наложение появляется после закрытия ChildWindow, то это известная ошибка.Вот обходной путь.

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