Многострочный текст в динамически изменяемом TextBlock

Привет, поэтому я пытаюсь вставить чат twitch в TextBlock, и он отлично работал, просто используя mvvm с текстовым блоком, но теперь я хочу на самом деле раскрасить имя пользователя и не знаю, как сделать это многострочное, потому что то, что у меня есть сейчас, это просто заменяет предыдущее сообщение, поэтому мне нужна помощь, чтобы двигаться вперед. Спасибо!\

Xaml:

<TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Background="Gainsboro" FontSize="14" Text="" Margin="5,5,5,5">
            <Run Text="{Binding Username, Mode=OneWay}" Foreground="{Binding UsernameColor, Mode=OneWay}" />
            <Run Text="{Binding Message, Mode=OneWay}" />
</TextBlock>

Мероприятие:

private void Client_OnMessageReceived(object sender, OnMessageReceivedArgs e)
        {
            Username = $"{e.ChatMessage.DisplayName}:";
            Message = e.ChatMessage.Message;
            UsernameColor = e.ChatMessage.ColorHex;
        }

поэтому проблема в том, что я хочу, чтобы он был многострочным и не заменял Runs каждый раз, когда приходит сообщение.


person Pato Srna    schedule 13.07.2020    source источник
comment
@вы хотите создать новый <Textblock> для каждого сообщения?   -  person dbvega    schedule 13.07.2020
comment
@dbvega нет, я бы хотел иметь только один текстовый блок   -  person Pato Srna    schedule 13.07.2020
comment
тогда проблема в том, что вам нужно сделать его многострочным? ЧТОБЫ решить многострочную проблему, измените ее на <Run .../>, затем на <LineBreak/>, затем на <Run .../>.   -  person dbvega    schedule 13.07.2020
comment
В чем причина использования только одного TextBlock? Это больше похоже на вариант использования элемента управления.   -  person thatguy    schedule 13.07.2020


Ответы (1)


Я думаю, что вы придерживаетесь неправильного подхода. Вы должны видеть чат как набор сообщений. Вы хотите отображать каждое сообщение отдельно по мере их поступления. Это говорит об использовании ListBox, где каждый элемент представляет отдельное сообщение:

ChatMessage.cs

class ChatMessage : INotifyPropertyChanged
{
  private string username;
  public string Username
  {
    get => this.username;
    set
    {
      this.username = value;
      OnPropertyChanged();
    }
  }

  private string message;
  public string Message
  {
    get => this.message;
    set
    {
      this.message = value;
      OnPropertyChanged();
    }
  }

  private string colorValue;
  public string ColorValue
  {
    get => this.colorValue;
    set
    {
      this.colorValue = value;
      OnPropertyChanged();
    }
  }

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

ViewModel.cs

class ViewModel : INotifyPropertyChanged
{
  public ObservableCollection<ChatMessage> Messages { get; set; }

  private void Client_OnMessageReceived(object sender, OnMessageReceivedArgs e)
  {
    var chatMessage = new ChatMessage
    { 
      Username = $"{e.ChatMessage.DisplayName}:",
      Message = e.ChatMessage.Message
      UsernameColor = e.ChatMessage.ColorHex
    }
    this.Messages.Add(chatMessage);
  }

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

MainWindow.xaml

<Window>
  <Window.DataContext>
    <ViewModel />
  <Window.DataContext>

  <ListBox ItemsSource="{Binding Messages}"
           IsHitTestVisible="False">
    <ListBox.ItemTemplate>
      <DataTemplate DataType="{x:Type ChatMessage}">
        <StackPanel Orientation="Horizonatal">
          <TextBlock Text="{Binding Username}" 
                     Foreground="{Binding ColorValue}" />
          <TextBlock Text="{Binding Message}" />
        </StackPanel>
      </DataTemplate >
    </ListBox.ItemTemplate>
  </ListBox ItemsSource="{Binding Messages}">
</Window>
person BionicCode    schedule 13.07.2020
comment
Вы совершенно правы, сэр, я посмотрел на это не под тем углом, спасибо раз! Думаю, я не практиковался, к сожалению - person Pato Srna; 13.07.2020
comment
Я рад, что смог помочь. Вы можете легко стилизовать ListBoxItem, чтобы удалить внешний вид списка. Вы можете установить для ListBoxItem.IsHitTestVisible значение false, чтобы отключить выделение и выделение. Я думаю, что даже должно быть достаточно отключить проверку попадания в ListBox вместо элементов. - person BionicCode; 13.07.2020