如何更改列表框中的所有项目

Posted

技术标签:

【中文标题】如何更改列表框中的所有项目【英文标题】:How to change all items in the ListBox 【发布时间】:2022-01-14 12:04:04 【问题描述】:

我使用 DataTemplate 重复生成我的 ListBox 的内容。 xml代码如下:

    <DataTemplate x:Key="singleUnit">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Binding fileName" FontSize="20" Foreground="Binding color" HorizontalAlignment="Left" VerticalAlignment="Top"/>
            <TextBlock/>
        </StackPanel>
    </DataTemplate>

    <ListBox Name="MyListBox" Width="300" Height="600">
    </ListBox>

而cs代码是:

private void Show()

    const int TotalCount = 100;
    for (int i = 0; i < TotalCount; i++)
    
        ContentControl cc = new ContentControl();
        cc.ContentTemplate = this.Resources["singleUnit"] as DataTemplate;
        DataModel dm = new DataModel();
        dm.fileName = "myfile" + i;
        dm.color = new SolidColorBrush(Colors.Blue);
        cc.Content = dm;
        MyListBox.Items.Add(cc);
    

    MyListBox.ScrollIntoView(MyListBox.Items[TotalCount / 2]);

以上代码将生成以下 UI:

我希望改变所有项目的颜色:目前每个项目,文件名的前景色是蓝色的。我希望在按下按钮时将其更改为绿色。

这就像用户通过一些选择操作来改变颜色主题。当颜色改变时,所有其他的东西都不应该改变,例如。滚动条的位置。

难点在于我使用模板来生成内容,以及如何对每一项进行迭代和修改。

我将可行的演示代码放在我的 Github 上: https://github.com/tomxue/ChangeListBox.git 你可以从它开始。 谢谢!

【问题讨论】:

this.MyListBox.Foreground = new SolidColorBrush(Colors.Green); 会将列表框中的所有文本更改为绿色。 完全不清楚为什么要在代码中创建 ContentControls,将数据项分配给它们的 Content 属性并将它们添加到 ListBox 的 Items 集合中。使用 ListBox 的典型方法是将一组数据项分配给 ItemsSource 属性。 DataTemplate 将用作 ListBox 的 ItemTemplate。 【参考方案1】:

我让你的代码工作了,但它仍然不完全正确,因为你应该为每个视图都有一个视图模型并在它们之间绑定。 您的 MainForm - 应该有一个 MainFormViewModel。 您的文件项 - 应该有 VmFile(或我在示例中写的 ViewModelFile) 您应该使用 ICommand 来绑定按钮,而不是像您那样使用事件。 简而言之,我认为您使用 MVVM 工作不正确,我建议您阅读有关 MVVM 的更多信息。

复制到您的 .xaml 文件:

 <Window x:Class="WpfApp14.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:WpfApp14"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        
        <Grid>
            <ListBox Name="MyListBox" Width="300" Height="600">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Binding FileName" FontSize="20" Foreground="Binding Color"
                                       HorizontalAlignment="Left" VerticalAlignment="Top"/>
                            <TextBlock/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
    
            </ListBox>
            <Button Content="Change color theme" HorizontalAlignment="Left" Margin="56,126,0,0" VerticalAlignment="Top" Width="164" Click="Button_Click" Height="36"/>
        </Grid>
    </Window>

复制到您的 .cs 文件:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp14

    public class ViewModelFile : INotifyPropertyChanged
    
        private string filename;
        private SolidColorBrush solidColorBrush;

        public event PropertyChangedEventHandler PropertyChanged;

        public string FileName 
         
            get =>filename;
            set 
            
                filename = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FileName)));
            
        

        public SolidColorBrush Color
        
            get => solidColorBrush;
            set
            
                solidColorBrush = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Color)));
            
        

        
    

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    
        public MainWindow()
        
            InitializeComponent();

            Refresh();
        

        private void Refresh()
        
            const int TotalCount = 100;
            for (int i = 0; i < TotalCount; i++)
            
                ViewModelFile vm = new ViewModelFile
                
                    FileName = "myfile" + i,
                    Color = new SolidColorBrush(Colors.Blue)
                ;
                MyListBox.Items.Add(vm);
            
            MyListBox.ScrollIntoView(MyListBox.Items[TotalCount / 2]);
        

        private void Button_Click(object sender, RoutedEventArgs e)
        
            // Do something to change all fileName items' forground color to red.
            // For example if user changes the color theme, and we should just change some UI color
            // while not changing any other part, e.g. the position of scrollbar
            foreach (var item in MyListBox.Items)
                ((ViewModelFile)item).Color = new SolidColorBrush(Colors.Red);
        
    

【讨论】:

以上是关于如何更改列表框中的所有项目的主要内容,如果未能解决你的问题,请参考以下文章

更改 tkinter 列表框中的项目顺序

如何在选中复选框时选择列表框中的所有项目?

如何重命名列表框中的项目? [关闭]

如何使 WPF 列表框中的列对于所有项目具有相同的宽度?

C#如何匹配两个列表框中的项目

WPF:停止或反转列表框中的选择更改