【问题标题】:WPF Listbox SelectedItem changing twice (bug?)WPF Listbox SelectedItem 更改两次(错误?)
【发布时间】:2014-01-11 11:23:02
【问题描述】:

我的自定义 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

E F G H

I J K L

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

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

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

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

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

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

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

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

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

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

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

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

【问题讨论】:

  • 您的 XAML 在我的测试环境中完美运行。请查看您的 ActiveAccent 设置器是否从您的代码中多次调用(由用户触发)。
  • 似乎列表框不是问题,而是它周围的 xaml。我将其缩小到 SharedSizeGroup。请参阅更新的 xaml 和说明。虽然仍然没有修复
  • 嗯,即使你的更新版本在我的机器上也能完美运行。
  • 这里肯定不行。它与sharedsizegroup有关。每当我删除它时,它就会开始工作。也许这与 MahApps.Metro ThemeManager 有关。我看到它做了一些内部方法调用(即它调用 'typeof(SystemParameters).GetMethod("InvalidateCache")
  • 好的.. 当我不调用 MahApps.Metro 的 ThemeManager 时,它也能正常工作。我怀疑这些内部方法调用(SystemParameters.InvalidateCache 和 SystemResources.InvalidateResources)与网格的呈现冲突。

标签: c# wpf listbox mahapps.metro


【解决方案1】:

我发现发生了什么。

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

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

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

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

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

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

感谢大家对此的调查!

【讨论】:

    【解决方案2】:

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

    <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>
    

    【讨论】:

    • 我将范围缩小到 SharedSizeGroup。查看更新的 xaml 和说明。
    • 我认为,它与您的绑定,可能是您调用您的 NotityOfPropertyChanged("SelectedItemProperty");两次
    猜你喜欢
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2023-04-06
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多