WPF TextBlock 绑定到 ViewModel 使用 TextBlock 扩展不起作用

时间:2021-01-02 18:33:20

标签: wpf mvvm textblock

我正在将视图模型绑定到 TextBlockInlines 属性不是 DependencyProperty,因此我创建了一个 TextBlockExtensions 类并创建了一个名为 DependencyProperty 的附加 BindableInlines

下面是我的视图模型。

public class MainWindowModel: INotifyPropertyChanged
{
    private buttonAddNewTextCommand _btnAddNewTextCommand;

    public ObservableCollection<Inline> ProcessTrackerInlines { get; set; }

    public ICommand btnAddNewTextCommand
    {
        get
        {
            return _btnAddNewTextCommand;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public MainWindowModel()
    {
        _btnAddNewTextCommand = new buttonAddNewTextCommand(this);
        loadProcessTracker();
    }

    public void addErrorLine(String errorMessage)
    {
        addText(errorMessage, Brushes.Red, true);
    }

    public void addNewTextLine()
    {
        String message = Guid.NewGuid().ToString();
        var rand = new Random();
        byte[] brushes = new byte[4];
        rand.NextBytes(brushes);
        ProcessTrackerInlines.Add(new LineBreak());
        ProcessTrackerInlines.Add(addText(message, new SolidColorBrush(Color.FromArgb(brushes[0], brushes[1], brushes[2], brushes[3])), true));
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("ProcessTrackerInlines"));
        }
    }

    private void loadProcessTracker()
    {
        ProcessTrackerInlines = new ObservableCollection<Inline>();
        var rand = new Random();
        byte[] brushes = new byte[4];
        for(int i=0; i<5; i++)
        {
            rand.NextBytes(brushes);
            ProcessTrackerInlines.Add(addText($"{Guid.NewGuid().ToString()}\r\n", new SolidColorBrush(Color.FromArgb(brushes[0], brushes[1], brushes[2], brushes[3])), true));
        }

    }

    private Run addText(String textToAdd, Brush foreground = null, Boolean? addTime = null)
    {
        if (addTime ?? false)
        {
            textToAdd = addCurrentTime(textToAdd);
        }
        if (foreground != null)
        {
            return new Run(textToAdd) { Foreground = foreground };
        }
        else
        {
            return new Run(textToAdd);
        }
    }

    private String addCurrentTime(String prefixText)
    {
        return $"[{DateTime.Now.ToString("h:mm ss tt")}] {prefixText}";
    }
}

public class buttonAddNewTextCommand : ICommand
{
    private MainWindowModel owner;

    public buttonAddNewTextCommand(MainWindowModel _object)
    {
        owner = _object;
    }

    public Boolean CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        owner.addNewTextLine();
    }

    public event EventHandler CanExecuteChanged;
}

我的 TextBlockExtensions 课:

public class TextBlockExtensions
{
    public static IEnumerable<Inline> GetBindableInlines(DependencyObject obj)
    {
        return (IEnumerable<Inline>)obj.GetValue(BindableInlinesProperty);
    }

    public static void SetBindableInlines(DependencyObject obj, IEnumerable<Inline> value)
    {
        obj.SetValue(BindableInlinesProperty, value);
    }

    public static readonly DependencyProperty BindableInlinesProperty =
        DependencyProperty.RegisterAttached("BindableInlines", typeof(IEnumerable<Inline>), typeof(TextBlockExtensions), new PropertyMetadata(null, OnBindableInlinesChanged));

    private static void OnBindableInlinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var Target = d as TextBlock;

        if (Target != null)
        {
            Target.Inlines.Clear();
            Target.Inlines.AddRange((System.Collections.IEnumerable)e.NewValue);
        }
    }
}

还有我的 XAML:

<Window x:Class="MVVMTextBlock.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:MVVMTextBlock"
        xmlns:viewModels="clr-namespace:MVVMTextBlock.ViewModels"
        xmlns:extensions="clr-namespace:MVVMTextBlock"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <viewModels:MainWindowModel/>
    </Window.DataContext>
    <Grid>
        <TextBlock extensions:TextBlockExtensions.BindableInlines="{Binding ProcessTrackerInlines, Mode=OneWay}" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="578" Margin="25,0,0,0" Height="398"/>
        <Button Content="Add New Text" HorizontalAlignment="Left" VerticalAlignment="Top" Width="123" Margin="638,10,0,0" Command="{Binding btnAddNewTextCommand, Mode=OneWay}"/>
    </Grid>
</Window>

点击按钮时,MainWindowModel.addNewTextLine() 方法被点击,但 TextBlockExtensions.OnBindableInlinesChanged() 没有被点击。所以 TextBlock 没有得到更新。 我已经将 BindableInlinesProperty 更改为 ObservableCollection 但它不起作用。 我做错了什么?

0 个答案:

没有答案