【问题标题】:Scrollviewer around itemstemplate picking up wrong itemstemplate围绕项目模板的滚动查看器拾取错误的项目模板
【发布时间】:2015-12-21 19:41:38
【问题描述】:

我需要一个围绕 ItemsControl 的滚动查看器,它的 ItemsPaneltemplate 取决于属性 IsClusterSupported。 如果没有 ScrollViewer,ItemsControl 总是显示正确的 ItemsPanel,但是当我添加滚动查看器代码时,即使 IsClusterSupported=False,也会显示 ClusterMapItemsPanelTemplate。

这里可能发生了什么错误?我附上了下面的代码。

<Grid Name="MapGrid">
    <ScrollViewer>
        <ScrollViewer.Style>
            <Style TargetType="{x:Type ScrollViewer}">
                <Setter Property="VerticalScrollBarVisibility" Value="Hidden"/>
                <Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsScrollingSupported}" Value="True">
                        <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
                        <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ScrollViewer.Style>
        <ItemsControl Name="ItemsControlInnerMap" Loaded="ItemsControlInnerMap_Loaded"
              ItemsSource="{Binding ItemsCol}" Tag="{Binding IsClusterSupported, PresentationTraceSources.TraceLevel=High}">
            <ItemsControl.Style>
                <Style TargetType="{x:Type ItemsControl}">
                    <Setter Property="ItemsPanel" Value="{StaticResource MapItemsPanelTemplate}"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsClusterSupported}" Value="True">
                            <Setter Property="ItemsPanel" Value="{StaticResource ClusterMapItemsPanelTemplate}"/>
                            <Setter Property="ItemContainerStyle" Value="{StaticResource ClusterMapGridContainerStyle}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ItemsControl.Style>

            <ItemsControl.ItemTemplate>
                <DataTemplate>
                  <Border>
                    <TextBlock Text="{Binding LabelTxt}"/>
                  </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

            <ItemsControl.GroupStyle>
                <GroupStyle x:Name="MyGroup">

                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Border Name="BD" BorderBrush="Black" BorderThickness="2">
                                            <ItemsPresenter Name="ClusterPresenter" Tag="{Binding Name}"/>
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <DataTrigger Binding="{Binding Name, Converter={StaticResource BorderVisibilityConvertor}}" Value="false">
                                                <Setter TargetName="BD" Property="BorderBrush" Value="Transparent"/>
                                            </DataTrigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                            <!--http://stackoverflow.com/questions/17863271/wpf-using-grid-as-itemshost-stacking-multiple-items-in-single-cell-automatical-->
                            <Setter Property="Grid.Row" Value="{Binding Items[0].ClusterGridRow}"/>
                            <Setter Property="Grid.Column" Value="{Binding Items[0].ClusterGridColumn}"/>
                            <Setter Property="Margin" Value="5"/>
                        </Style>
                    </GroupStyle.ContainerStyle>

                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <Grid Name="ClusterMapGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                                  Loaded="ClusterMapGrid_Loaded"
                                  MaxHeight="{Binding AllowedMaxHeight}" MaxWidth="{Binding AllowedMaxWidth}"
                                  MinHeight="{Binding ReqMinHeight}" MinWidth="{Binding ReqMinWidth}">
                            </Grid>ReqMinHeight
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>

                </GroupStyle>
            </ItemsControl.GroupStyle>
        </ItemsControl>
    </ScrollViewer>
</Grid>

RDV(01/04/2016):我在这里发现了一些有趣的东西,希望能更接近解决方案,但仍然需要帮助。

  1. 我所有的绑定都工作正常;我在没有滚动查看器的情况下进行了调试,并在 ItemsControl 中看到了正确的 ItemsPanel。 ItemsControl 的 IsGrouping 属性也设置正确。

  2. 当我在 ItemsControl 周围有一个滚动查看器时,无论我是否有集群,都会加载 ClusterMapGrid(GroupStyle.Panel)。加载后,不会加载非集群模板 (MapsItemsPanelTemplate)。

  3. 为了解决这个问题,我尝试将 ClusterMapGrid Visibility 绑定到 ItemsControl 的 IsGrouping 属性,但在 scrollviewer 的情况下再次以某种方式加载 ClusterMapGrid,并且一旦加载非集群模板就无法加载。

  4. 我使用 snoop 检查 ClusterMapGrid 的可见性,我可以看到它已折叠,但如果在 snoop 中手动将其更改为任何其他值,非集群模板加载并且一切正常。我尝试在 ClusterMapGrid_Loaded 事件中将可见性设置为折叠,但它也没有帮助。

  5. 进一步调试我发现 ScrollViewer 正在加载其中的所有项目 - 因此 ClusterMapGrid 已加载,一旦我使用 Snoop 更改可见性,它会在非集群情况下被卸载。

问题陈述:加载后如何卸载 ClusterMapGrid,我知道这是一个非集群方案。

【问题讨论】:

  • ItemsControl 上显式设置DataContext 会起作用吗? &lt;ItemsControl DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ScrollViewer}}" ... &gt;
  • 另外,在Output 窗口中查看任何绑定/应用程序错误并更新问题以告诉我们它们是什么(如果有)。
  • 我验证(使用 snoop 和附加调试器)ItemsControl 的 Tag 属性已根据 IsClusterSupported 值正确设置。由于某种原因,PresentationTraceSources.TraceLevel=High 不起作用。
  • 您在测试时是在 Debug 还是 Release 配置下运行?您是否注意到 PresentationTraceSources 因构建配置而异?
  • 您可能希望将项目面板数据触发器绑定到ItemsControlInnerMap.Tag,而不是IsClusterSupported

标签: wpf scrollviewer itemscontrol


【解决方案1】:

问题是 ScrollViewer 会在 XAML 中初始化并加载所有内容,即使它不是要加载的(例如,如果 ItemsControl 上的 IsGrouping 为 true,则应该加载 GroupStyle.Panel,但使用 scrollviewer,无论如何它都会被加载) .

解决方案:从 XAML 中注释掉 GroupStyle.Panel,并将其作为 ItemsPanelTemplate 添加到资源中:

    <ItemsPanelTemplate x:Key="ClusterPanelTemplate">
                <Grid Name="ClusterMapGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"                                                                      
                      Loaded="ClusterMapGrid_Loaded"
                      MaxHeight="{Binding AllowedMaxHeight}" MaxWidth="{Binding AllowedMaxWidth}"
                      MinHeight="{Binding ReqMinHeight}" MinWidth="{Binding ReqMinWidth}"/>
   </ItemsPanelTemplate>

在 ItemsControlInnerMap_Loaded 事件代码隐藏中添加以下内容:

private void ItemsControlInnerMap_Loaded(object sender, RoutedEventArgs e)
        {
            if ((sender as ItemsControl).IsGrouping)
            {
                (sender as ItemsControl).GroupStyle[0].Panel = (ItemsPanelTemplate)this.FindResource("ClusterPanelTemplate");
            }
            else
            {
                (sender as ItemsControl).GroupStyle.Clear();
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多