【问题标题】:Change SelectedItem of ListBox from ViewModel从 ViewModel 更改 ListBox 的 SelectedItem
【发布时间】:2017-05-31 18:35:17
【问题描述】:

在 ViewModel 中设置 SelectedItem 后,如何使 ListBoxSelectedItem 突出显示?

ItemsSource 绑定到BarObservableCollection(集合是Foo 类的成员。按钮绑定到向集合添加新的空Bar 实例的命令然后还将SelectedItem 设置为新的空实例。

将实例添加到集合后,ListBox 会更新以显示新的空白 Bar。但是,在 ViewModel 中设置 SelectedItem 属性后,新实例不会在 ListBox 中突出显示,但它正在设置中并引发 PropertyChanged 事件(SelectedItem 显示在视图中的其他位置)。

其他细节:

INotifyPropertyChanged 在基础 ViewModel 类中实现,也在 FooBar 类中实现。

ListBox 包含一个自定义 ItemTemplate 以显示 Bar 成员,以及一个自定义 ItemContainerStyle 修改 BackgroundIsMouseOver 触发器。

简化的 xaml:

<ListBox ItemsSource="{Binding Path=MyFoo.BarCollection}"
         SelectedItem="{Binding Path=SelectedItem, 
                       UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

<Button Content="Add New Bar"
        Command="{Binding Path=AddBarCommand}"/>

简化的视图模型:

private Foo _myFoo;
public Foo MyFoo
{
    get { return _myFoo; }
    set { _myFoo= value; OnPropertyChanged("MyFoo"); }
}

private Bar _selectedItem;
public Bar SelectedItem
{
    get { return _selectedItem; }
    set { _selectedItem = value; OnPropertyChanged("SelectedItem"); }
}

private void AddBar()
{
    Bar newBar = new Bar();

    MyFoo.BarCollection.Add(newBar);
    SelectedItem = newBar ;
    _unsavedChanges = true;
}

【问题讨论】:

  • BarCollection的类型是什么?
  • @Ed BarCollectionObservableCollection&lt;Bar&gt;
  • 我认为它必须是。有了这个假设,您的代码对我来说效果很好。新项目是否有可能以一种非常淡的灰色突出显示,与它周围的窗口几乎无法区分?现代版本的 Windows 中默认的非聚焦突出显示背景颜色可能非常难以注意到。如果是这样,它很容易修复。
  • @Ed Ughh...是的!将ListBox背景改为白色,新添加的项确实是LightGray高亮。猜猜我会覆盖 SystemColor 画笔?谢谢!

标签: c# wpf mvvm .net-4.0 selecteditem


【解决方案1】:

您的代码非常适合我。

注意“栏 3” 被选中,但是当列表框没有焦点时,Windows 7 上的默认主题很难让您注意到。 Windows 7 甚至不是最差的。我们的应用程序使用WhiteSmoke 作为默认背景,我们遇到了老用户1 无法判断列表框项目是否被选中的重大问题。

幸运的是,这是一个微不足道的修复。这些资源可以很容易地采用Window.Resources、全局ListBox 样式或App.xaml。这取决于您想应用它们的范围。

<ListBox 
    ItemsSource="{Binding MyFoo.BarCollection}"
    SelectedItem="{Binding SelectedItem}"
    >
    <ListBox.Resources>
        <SolidColorBrush 
            x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
            Color="{x:Static SystemColors.HighlightColor}"
            Opacity="0.5"
            />
        <SolidColorBrush 
            x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" 
            Color="{x:Static SystemColors.HighlightTextColor}"
            />
    </ListBox.Resources>
</ListBox>

1 “老”的意思是可以投票。


如果您的 .NET 版本早于 SystemColors.InactiveSelectionHighlightTextBrushKey 的存在,这可能需要一些改进,但它确实有效:

<ListBox
    >
    <ListBox.ItemContainerStyle>
        <Style 
            TargetType="ListBoxItem" 
            BasedOn="{StaticResource {x:Type ListBoxItem}}"
            >
            <Style.Setters>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Grid
                                Background="{TemplateBinding Background}"
                                >
                                <ContentPresenter />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter 
                        Property="Background" 
                        Value="{StaticResource {x:Static SystemColors.HighlightBrushKey}}" 
                        />
                    <Setter 
                        Property="Foreground" 
                        Value="{StaticResource {x:Static SystemColors.HighlightTextBrushKey}}" 
                        />
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="True" />
                        <Condition Property="IsEnabled" Value="False" />
                    </MultiTrigger.Conditions>
                    <Setter 
                        Property="Background" 
                        Value="{StaticResource {x:Static SystemColors.InactiveCaptionBrushKey}}" 
                        />
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

【讨论】:

  • 正是我遇到的问题。感谢您的修复!标记为答案。 (抱歉,对 +1 了解不够)
  • NP,很高兴为您提供帮助。
  • 覆盖InactiveSelectionHighlightBrushKey 成功了,尽管它破坏了 VS2010 中的设计器。 Microsoft docs 也说,“画笔的IsFrozen 属性是true,所以不能修改。”这有什么好担心的吗?
  • 你没有改变画笔资源;您只是在更本地的范围内创建一个具有相同密钥的新密钥,因此FindResource()(或任何实际工作的人)将首先找到您的密钥并停止查找。不过,这对破坏设计师来说是不幸的。
  • 对于其他停留在较旧的 .NET 框架上的人,我遇到了 this SO answer,它指出:“如果系统只有 .NET FW 4.0,当系统创建用户控件时会抛出异常InactiveSelectionHighlightBrushKey。”他们建议在 LostFocus/LostKeyboardFocus/GotFocus 的处理程序中设置颜色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
相关资源
最近更新 更多