选择 ListboxItem 而不是 Index(突出显示,因为我会单击它)

2024-03-02

关于我的项目:我想通过索引突出显示搜索功能列表框项目。

当前阶段:

private void Menu_Search_Click(object sender, RoutedEventArgs e)
{
    search_person= Interaction.InputBox("Search by Name","Search...","Input Name");
    int index;
    foreach (person f in personlist) // it is an Observable Collection which works perfectly fine for me                                                                                                                               {

        if (f.name == search_person)
        {
            index = listbox.Items.IndexOf(f);
            // Here code to Highlight the (maybe) multiple objects inside the Listbox
            InfoPanel.Text += index.ToString(); // this i used to test if i get all index integers for persons inside my personlist (which seems to work perfectly fine)
        }
    }
}

列表框本身是通过 WPF XAML 创建的,并且具有到包含 person 类对象的 Observable Collection 的数据绑定。 有没有一种很好且正确的方法来突出显示(例如选择)我在搜索中找到的列表框项目?


可以用以下方法完成Binding, DataTrigger and INotifyPropertyChanged接口实现(WPF 的强大功能广泛应用于MVVM https://learn.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern编程模式)。

我将使用 MVVM 方法作为您要求的示例。

示例功能

  • 用户可以输入任意文本TextBox并按Search按钮,所有包含搜索文本的项目将以黄色背景突出显示。

第 0 步:助手

以下类需要通知 UI 有关属性的更改。我将从其他类中派生并简单地调用OnPropertyChanged()在属性设置器中。

通知属性更改.cs

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

在 MVVM 中,开发人员不使用Click活动因为有更强大的Command存在。下一堂课实施ICommand接口(从上面链接的文档页面获取)。它需要在主代码中轻松实现命令。

RelayCommand.cs

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
    public void Execute(object parameter) => _execute(parameter);
}

第 1 步:数据

人物.cs

public class Person : NotifyPropertyChanged
{
    private bool _highlighted;

    public string Name { get; set; }
    public bool Highlighted
    {
        get => _highlighted;
        set
        {
            _highlighted = value;
            OnPropertyChanged();
        }
    }
}

第2步:查看模型

查看模型 in MVVM是类哪里View(UI/XAML) 可以设置其DataContext这需要Binding.

MainViewModel.cs

public class MainViewModel : NotifyPropertyChanged
{
    private ObservableCollection<Person> _persons;
    private ICommand _searchCommand;

    public ObservableCollection<Person> Persons
    {
        get => _persons;
        set
        {
            _persons = value;
            OnPropertyChanged();
        }
    }

    // It's C# 8.0 but for earlier versions of C# use the following:
    //                               _searchCommand ?? (_searchCommand = new ...
    public ICommand SearchCommand => _searchCommand ??= new RelayCommand(parameter =>
    {
        if (parameter is string searchText)
        {
            foreach(Person person in Persons)
            {
                person.Highlighted = searchText.Length > 0 && person.Name.Contains(searchText, StringComparison.InvariantCultureIgnoreCase);    
            }
        }
    });
    // }));

    public MainViewModel()
    {
        // example data
        Persons = new ObservableCollection<Person>
        {
            new Person { Name = "Alex" },
            new Person { Name = "Jane" },
            new Person { Name = "Nick" },
            new Person { Name = "John" },
            new Person { Name = "Brett" },
            new Person { Name = "Peter" },
            new Person { Name = "Mike" },
            new Person { Name = "George" },
            new Person { Name = "Anthony" }
        };
    }
}

第三步:查看

我提供完整的标记以使一切变得清晰。这是DataContext设置和所有控件。

主窗口.xaml

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <TextBox x:Name="SearchTextBox" Width="300" Margin="5"/>
            <Button Content="Search" Margin="5" Command="{Binding SearchCommand}" CommandParameter="{Binding Text,ElementName=SearchTextBox}"/>
        </StackPanel>
        <ListBox Margin="5" Grid.Row="1" ItemsSource="{Binding Persons}">
            <ListBox.Resources>
                <Style TargetType="ListBoxItem">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Highlighted}" Value="True">
                            <Setter Property="Background" Value="Yellow"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

就是这样。

附:代码隐藏类:)

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

Updated

如果我对问题的理解错误并且您需要自动选择而不是突出显示,则可以按以下方式更改代码:

人物.cs

public class Person : NotifyPropertyChanged
{
    private bool _selected;

    public string Name { get; set; }
    public bool Selected
    {
        get => _selected;
        set
        {
            _selected = value;
            OnPropertyChanged();
        }
    }
}

MainViewModel.cs

public ICommand SearchCommand => _searchCommand ??= new RelayCommand(parameter =>
{
    if (parameter is string searchText)
    {
        foreach(Person person in Persons)
        {
            person.Selected = searchText.Length > 0 && person.Name.Contains(searchText, StringComparison.InvariantCultureIgnoreCase);    
        }
    }
});

主窗口.xaml

<ListBox Margin="5" Grid.Row="1" ItemsSource="{Binding Persons}" SelectionMode="Extended">
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding Selected}"/>
        </Style>
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

选择 ListboxItem 而不是 Index(突出显示,因为我会单击它) 的相关文章

  • Qt 5 和 QProcess 使用信号/槽 read 重定向标准输出

    这个问题困扰着我 因为它应该有效 但遗憾的是它没有 我试图实现的是读取某个进程的标准输出并让另一个进程处理它 即打印出来 产生输出的过程如下所示 include
  • 使用 C# 在 Windows 窗体应用程序中正确使用 OnClick 与 MouseClick 事件

    我目前正在开发一个自定义控件 并意识到我的代码正在运行两次 这实际上并不是一个大问题 它只是 Focus 方法调用 不过 我想了解一下 从阅读点击 MSDN说明单击事件 http msdn microsoft com en us libra
  • C# 3 新功能帖子(与 .Net 3.5 功能无关)[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions Net F
  • 获取在 Unity 中实现接口的所有类型

    如果您只想知道解决方案 请跳至更新 我有一个应用程序 它使用以下代码来获取并运行许多工作方法 var type typeof IJob var types AppDomain CurrentDomain GetAssemblies Sele
  • Microsoft.Web.Administration 内存泄漏

    拥有一个 Windows 服务 除其他外 还可以监视 IIS 应用程序池 如果任何池已配置应用程序但未运行 则该池 池 将启动 这已经运行良好一段时间了 最近发现该服务存在内存泄漏 查看内存转储 罪魁祸首是用于检查应用程序池的 Micros
  • 如何将带有自定义标头的任意 JSON 数据发送到 REST 服务器?

    TL DR 如何将 JSON 字符串发送到带有 auth 标头的 REST 主机 我尝试了 3 种不同的方法 发现一种适用于匿名类型 为什么我不能使用匿名类型 我需要设置一个名为 Group Name 的变量 并且连字符不是有效的 C 标识
  • 未构建 csproj 时抑制 AfterBuild 目标

    我在 MSBuild 中有一个构建后目标来复制一些构建输出 这是 linkedin 作为对AfterBuild目标 暴露于Microsoft CSharp targets
  • send() 使我的程序崩溃

    我正在运行服务器和客户端 我正在我的计算机上测试我的程序 这是服务器中向客户端发送数据的函数 int sendToClient int fd string msg cout lt lt sending to client lt lt fd
  • GridView必须添加到表单标签中才能渲染

    TextWriter tr new StringWriter HtmlTextWriter writer new HtmlTextWriter tr HtmlForm form new HtmlForm form Controls Add
  • 数据绑定问题,请解释

    public partial class Form1 Form MyClass myClass new MyClass one two public Form1 InitializeComponent textBox1 DataBindin
  • C# 如何在没有 GacUtil 的情况下在 GAC 中注册程序集?

    我需要使用批处理文件在 GAC 中注册程序集 有没有办法找到安装位置GacUtil exe或者有没有办法在没有 GacUtil 的情况下注册程序集 Your bestbet is to use a powershell script tha
  • const int 列表而不是 enum

    我开始研究大型 C 代码库 并发现使用带有多个 const ints 字段的静态类 这个类的行为与枚举完全一样 我想将类转换为实际的枚举 但权力被拒绝 我想转换它的主要原因是这样我可以将枚举作为数据类型而不是 int 这对可读性有很大帮助
  • cygwin $'\r':命令未找到错误

    我稍微修改了一个项目 在调试下它运行得很好 当我尝试在不调试的情况下构建它时 它显示错误 无法修复它 make Making all in third party make 1 Entering directory cygdrive c U
  • CGAL:如何有效计算多面体的面面积?

    我有一个多面体 其面是三角形 我知道在 CGAL 中 Triangle 3 类提供了 squared area 方法 通过它我们可以计算三角形的面积 有什么方法可以将其应用到多面体方面吗 或者关于如何计算每个面的面积有什么想法吗 这是一个例
  • 计算距离早上 8 点还有多少小时

    我知道如何计算两个日期之间的差异 但如何计算给定日期与下一个上午 8 点之间的时间 var now DateTime Now var tomorrow8am now AddDays 1 Date AddHours 8 double tota
  • 如何防止用户生成的 Sql 查询上的 Sql 注入

    我有一个项目 私有的 ASP net 网站 受 https 密码保护 其中要求之一是用户能够输入直接查询数据库的 Sql 查询 我需要能够允许这些查询 同时防止它们对数据库本身造成损坏 以及访问或更新它们不应该访问 更新的数据 我制定了以下
  • 使用 C++20 概念避免 std::function

    过去 当我想要回调作为函数参数时 我通常决定使用std function 在极少数情况下 我绝对从不使用捕获 我使用了typedef改为函数声明 因此 通常我的带有回调参数的声明看起来像这样 struct Socket void on re
  • 写入 Windows 7“预览”窗口区域

    如何使用 C 将控件写入或绘制到 Windows 7 预览区域 作为我正在讨论的示例 请在 Windows 7 中打开 Windows Media Player 并播放一首歌曲 播放歌曲时 最小化 Windows Media Player
  • Microsoft Graph API 调用无限期挂起

    我正在尝试使用 Microsoft Graph 查询 Azure Active Directory 用户信息 我可以很好地进行身份验证 但是当我尝试查询用户信息时client Users我的应用程序无限期挂起 没有超时 没有错误 只是挂起
  • 在实体框架中比较日期的最佳方法

    我在实体框架的 where 子句中使用日期并收到以下错误 这是由于以下代码 var entity dbContext MyTable Where w gt w PId 3 w CreatedOn Date mydate Date First

随机推荐