【问题标题】: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。

标签: c# wpf


【解决方案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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多