如何使用MVVM模式更改动态构建属性的部分的前景色

时间:2018-03-19 12:55:04

标签: c# wpf xaml mvvm

我有一个String属性,它充当文件的路径。

构建String并在填充Observable Collection时附加值。

Observable Collection是使用Student对象构建的,我正在构建的String引用了Student的Name属性。每个学生的姓名由|分隔它不需要着色,它应该保持黑色。

因此,例如,在我将三个学生添加到集合后,字符串应该如下所示:

[associatedColorForFirstStudent]firstStudentName | [associatedColorForSecondStudent]secondStudentName | [associatedColorForThirdStudent]thirdStudentName

注意:所有管道都是黑色的,而不是学生的任何相关颜色。

现在,我将String的整个前景设置为添加到Collection的最后一个学生的相关Brush。

所以,我的String看起来像

[thirdStudentsColor]firstStudentName | secondStudentName | thirdStudentName

我尝试使用<Run>标签做了一些事情,但它似乎没有用,它使整个字符串变黑。

<dxe:TextEdit Style="{StaticResource StudentFullPath}" Text="{Binding FullStudentPathText, UpdateSourceTrigger=PropertyChanged}" 
                              Foreground="{Binding AssociatedStudentBrush, UpdateSourceTrigger=PropertyChanged}"/>

在我的View Model中,我使用以下方法设置StudentFullPath属性:

private string ConfigureStudentFullPath(ObservableCollection<Student>Students)
{
    string path = "";
    foreach (Student s in Students)
    {
        path += "[" + s.Name + "]";
    } 
    return path;
}

注意:AssociatedStudentBrush是一个引用Student的Brush属性的属性。在添加单个学生时设置。

编辑:重复项对我不起作用,因为我试图尽可能地遵守MVVM设计模式。

1 个答案:

答案 0 :(得分:0)

这是我在可用时间内所做的最好的事情(更新以显示边框)。

查看-型号:

class MainWindowVm
{
    public MainWindowVm()
    {
        PathParts = new ObservableCollection<PathPart>();
        Path = new ObservableCollection<StudentData>();

        var allStudents = new ObservableCollection<StudentData>(new[]
                                                 {
                                                     new StudentData() { Name = "Bob", TextColor = Colors.Aqua },
                                                     new StudentData() { Name = "Mary", TextColor = Colors.Red },
                                                     new StudentData() { Name = "Joe", TextColor = Colors.Blue },
                                                     new StudentData() { Name = "Dan", TextColor = Colors.Green },
                                                 });

        Path.CollectionChanged += (sender, e) => { UpdatePath(); };

        //This should would normally be part of a button command, or something else that triggers a change to the path.
        Path.Add(allStudents[1]);
        Path.Add(allStudents[2]);
        Path.Add(allStudents[0]);
    }

    private void UpdatePath()
    {
        PathParts.Clear();
        foreach (var student in Path)
        {
            PathParts.Add(new PathPart() { Text = student.Name, Color = student.TextColor });
            if (student != Path.Last())
            {
                PathParts.Add(new PathPart() { Text = " | ", Color = Colors.Black });
            }
        }
    }

    public ObservableCollection<PathPart> PathParts { get; }
    public ObservableCollection<StudentData> Path { get; }
}

class PathPart
{
    public string Text { get; set; }
    public Color Color { get; set; }
}

class StudentData
{
    public string Name { get; set; }
    public Color TextColor { get; set; }
}

XAML:

<Window
    x:Class="WpfApp2.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:local="clr-namespace:WpfApp2"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:MainWindowVm />
    </Window.DataContext>
    <Border
        Margin="8"
        Padding="3"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        BorderBrush="Black"
        BorderThickness="1">
        <ItemsControl ItemsSource="{Binding Path=PathParts}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Text}">
                        <TextBlock.Foreground>
                            <SolidColorBrush Color="{Binding Path=Color}" />
                        </TextBlock.Foreground>
                    </TextBlock>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Border>
</Window>

我没有时间让所有内容都实现INotifyPropertyChanged,但 应该正确地流动。

它给了我这个结果:

Result