【问题标题】:Multiline text in dynamicaly changed TextBlock动态更改的 TextBlock 中的多行文本
【发布时间】:2020-07-13 15:20:01
【问题描述】:

嗨,所以我正在尝试将 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;
        }

所以问题是我希望它是多行的,而不是每次通过消息时都替换运行。

【问题讨论】:

  • @你想为每条消息创建一个新的&lt;Textblock&gt;吗?
  • @dbvega 不,我只想拥有一个文本块
  • 那么问题是你需要让它多行吗?要解决多行问题,请将其更改为 &lt;Run .../&gt; 然后 &lt;LineBreak/&gt; 然后 &lt;Run .../&gt;
  • 只使用一个TextBlock的原因是什么?这听起来更像是项目控件的用例。

标签: c# wpf binding textblock twitch


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

【讨论】:

  • 您说的完全正确好先生,我从错误的角度看它,谢谢您!我想我很遗憾没有练习
  • 我很高兴能帮上忙。您可以轻松地设置 ListBoxItem 的样式以删除列表外观。您可以将 ListBoxItem.IsHitTestVisible 设置为 false 以禁用选择和突出显示。我认为它甚至应该足以禁用 ListBox 而不是项目上的命中测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 2013-08-23
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多