1

我的自定义 WPF ListBox 有一个非常奇怪的问题:

<Grid Name="root"
      Margin="4"
      Grid.IsSharedSizeScope="True">
    <StackPanel>
        <Grid HorizontalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"
                                  SharedSizeGroup="hccFormStyleLabel" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Label Target="{Binding ElementName=Theme}"
                   HorizontalAlignment="Left"
                   Grid.Column="0"
                   Content="Theme:">
            </Label>
            <ListBox Grid.Column="1"
                     Name="Theme"
                     SelectionMode="Single"
                     Background="Transparent">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal"
                                   IsItemsHost="True" />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBoxItem IsSelected="{Binding IsThemeLight}">
                    <Grid Margin="0 4 4 0"
                          HorizontalAlignment="Center">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Content" />
                        </Grid.ColumnDefinitions>
                        <StackPanel Orientation="Vertical">
                            <Ellipse Width="16"
                                     Height="16"
                                     StrokeThickness="1"
                                     Stroke="{DynamicResource BlackBrush}"
                                     Fill="{DynamicResource BlackBrush}" />
                            <Label HorizontalAlignment="Center"
                                   Content="Light"></Label>
                        </StackPanel>
                    </Grid>
                </ListBoxItem>
                <ListBoxItem IsSelected="{Binding IsThemeDark}">
                    <Grid Margin="0 4 4 0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Content" />
                        </Grid.ColumnDefinitions>
                        <StackPanel Orientation="Vertical"
                                    HorizontalAlignment="Center">
                            <Ellipse Width="16"
                                     Height="16"
                                     StrokeThickness="1"
                                     Stroke="{DynamicResource BlackBrush}"
                                     Fill="{DynamicResource WhiteBrush}" />
                            <Label HorizontalAlignment="Center"
                                   Content="Dark"></Label>
                        </StackPanel>
                    </Grid>
                </ListBoxItem>
            </ListBox>
        </Grid>
        <Grid HorizontalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"
                                  SharedSizeGroup="hccFormStyleLabel"
                                  />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Label Target="{Binding ElementName=accentcolors}"
                   HorizontalAlignment="Left"
                   Grid.Column="0"
                   Content="Accent:">
            </Label>
            <ListBox Grid.Column="1"
                     Name="accentcolors"
                     ItemsSource="{Binding AccentColors, Mode=OneWay}"
                     SelectedItem="{Binding ActiveAccent, Mode=TwoWay}"
                     SelectionMode="Single"
                     Background="Transparent">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}" />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="0 4 4 0"
                              HorizontalAlignment="Center">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition SharedSizeGroup="Content" />
                            </Grid.ColumnDefinitions>
                            <StackPanel Orientation="Vertical"
                                        HorizontalAlignment="Center">
                                <Ellipse Width="16"
                                         Height="16"
                                         Margin="2"
                                         HorizontalAlignment="Center"
                                         Fill="{Binding ColorBrush}" />
                                <TextBlock HorizontalAlignment="Center"
                                           Text="{Binding Path=Name}" />
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </StackPanel>
</Grid>

这将呈现以下样式的列表框:

A B C D

EFGH

IJKL

现在,每当我单击 B - K 之一时,它“随机”选择其他项目之一,而不是我单击的项目。

奇怪的是,当我附加一个调试器并遍历所有属性设置器/获取器时,一切正常。当我在没有调试器的情况下运行它(或不中断)时,问题再次出现。

我已经在 viewmodel 属性的 getter 和 setter 中放置了 Log.Info 语句,看起来最初选择了正确的项目。但是在最初的“set_ActiveAccent 调用”之后,它再次被调用,在我看来是一个随机值。好像 WPF 检测到第二次鼠标单击另一个项目。

当我删除 ItemsPanel (WrapPanel) 时,它似乎可以工作,但是使用 WrapPanel 时,它又回到了这种奇怪的行为。

我排除了“宽度”绑定(如果我删除它,问题仍然存在)。

谁能告诉我这里发生了什么,或者我怎样才能更好地调查这个?

编辑:好的......这越来越奇怪了。当我使用鼠标右键选择其中一项时,它可以正常工作。所以“鼠标左键”发生了一些奇怪的事情

编辑:我将其缩小到“SharedSizeGroup”的问题。我更新了上面的 xaml 以显示我使用的完整 xaml。

当我删除 SharedSizeGroup='hccFormStyleLabel' (在 ColumnDefinition 上)时,一切都重新开始工作。做起来真的没有意义......

我想使用这个共享大小组,因为在我的应用程序中,我将上面的大部分 xaml 提取到了可重用的 HeaderedContentControl。(为了清楚起见,我在示例代码中删除了它)。

总结一下:当我设置一个 SharedSizeGroup 时,我得到了奇怪的双(随机)点击行为。没有它,它就可以工作。

有什么我能做的吗?也许还有另一个很好的可重复使用的解决方案来对齐我的表单标签而不是共享大小组?

4

2 回答 2

2

我发现发生了什么。

正如您可能已经猜到的那样,此 UI 用于更改应用程序的当前主题和口音。

我正在使用 MahApps.Metro 的 ThemeManager 来动态更改应用程序的主题和口音。

事实证明,MahApps ThemeManager 调用一些内部 WPF 方法来使系统资源和缓存无效(以解决动态更改资源时的一些问题)。

这与 SharedSizeGroup (或一般的布局渲染)相冲突。

目前,我使用的是 MahApps.Metro 的自定义版本,我在其中禁用了此解决方法。

我会将这个错误报告给 MahApps。

感谢大家对此进行调查!

于 2014-01-11T12:30:15.993 回答
0

我有一个类似的控件,可以按预期工作。请看一看。

<ListBox ItemsSource="{Binding AccentColors}"
                SelectedItem="{Binding SelectedAccentColor, Mode=TwoWay}"
                Margin="0,0,0,16">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel MaxWidth="{Binding ActualWidth, ElementName=Panel}" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem" BasedOn="{StaticResource FlatListBoxItem}">
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="40" Height="40" Margin="2" >
                <Rectangle.Fill>
                    <SolidColorBrush x:Name="Brush" Color="{Binding}" />
                </Rectangle.Fill>
            </Rectangle>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
于 2014-01-11T11:43:36.197 回答