【问题标题】:Change background on one List Item in a listbox (Not the selected item)更改列表框中一个列表项的背景(不是所选项目)
【发布时间】:2016-04-28 19:59:33
【问题描述】:

我有一个ListBox 用于addresses。每个项目都是使用DataTemplate 格式化的地址标签。

当用户在列表中选择一个项目并单击Set to default 按钮时,我想更改该项目的背景颜色以表示默认值。

我只想更改那一项,而不是 SelectedItem... 所以 SelectedItem 可能是一种颜色,而 DEFAULT 可能是另一种颜色。

我想务实地做这件事……即使我需要一个循环来重置非默认值并设置默认值……

我的问题是ListBox.SelectedItem 只允许我访问集合中的底层对象,在本例中为Address。

因此,以下内容将不起作用:

foreach (ListBoxItem item in lstShipToAddresses.Items)
{
   // does not work (can't cast Address to ListboxItem) 
   item.Background = Brushes.Magenta;        
}

如何访问特定ListBoxItem 的背景?

我有一个B 的计划,其中只涉及使用ListBox 之外的另一个区域来显示默认的address,但这会占用更多的屏幕空间,所以我试图避免这种情况。

更新 (XAML):

<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
         HorizontalAlignment="Stretch"
         HorizontalContentAlignment="Stretch"
         Name="lstShipToAddresses"
         ItemsSource="{Binding Path=ocShipToAddress}"
         SelectionChanged="lstShipToAddresses_SelectionChanged"
         SelectedValuePath="Address_ID">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="#FF000000" BorderThickness="2,2,2,2" CornerRadius="10" HorizontalAlignment="Stretch" >
                <Grid HorizontalAlignment="Stretch">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <StackPanel>
                        <TextBlock Grid.Row="0" Text="{Binding Path=Address_Label}" HorizontalAlignment="Stretch"></TextBlock>
                    </StackPanel>
                </Grid>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

最终解决方案:

此代码在按钮单击中完成,因此SelectedItem 是我们要设为默认值的代码。

for (int i = 0; i < lstShipToAddresses.Items.Count; i++)
{
    if (lstShipToAddresses.Items[i] == lstShipToAddresses.SelectedItem)
    {
        // Set background on default
        var listBoxItem = lstShipToAddresses.ItemContainerGenerator.ContainerFromIndex(i);
        (listBoxItem as ListBoxItem).Background = Brushes.Magenta;
    }
    else
    {
        // Reset background on non-default 
        var listBoxItem = lstShipToAddresses.ItemContainerGenerator.ContainerFromIndex(i);
        (listBoxItem as ListBoxItem).Background = Brushes.White;
    }
}
  • 可能需要将洋红色更改为不那么吓人的颜色 ;)

【问题讨论】:

  • 你可以使用ItemContainerStyle。
  • 如果您执行以下操作来查看它是否会更改颜色 @pStan item.Background = new SolidColorBrush(Colors.Red); 那么它是否使用您的 Magenta 颜色
  • 该项目属于“地址”类型,因此它没有“背景”属性
  • @pStan...你能展示你的 XAML 吗?
  • 你需要一个属性,比如 Background 或 IsDefault...

标签: c# wpf listbox listboxitem


【解决方案1】:

为此,您需要使用ItemContainerGenerator.ContainerFromIndex。它返回一个DependencyObject,然后您可以将其转换为ListBoxItem 并使用ListBoxItem 的属性,例如Background:

for (int i = 0; i < lstShipToAddresses.Items.Count; i++)
{
    var listBoxItem = lstShipToAddresses.ItemContainerGenerator.ContainerFromIndex(i);
    (listBoxItem as ListBoxItem).Background = Brushes.Magenta; 
}

【讨论】:

  • 感谢您的详尽回答。这就是我需要的。
  • @pStan...不客气。 :) 另外我认为,如果您更新您的问题并将其标题更改为Unable to cast object of type 'Address' to type 'System.Windows.Controls.ListBoxItem'.,您将帮助未来的访问者更多地找到您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多