I'm using a RadChat in my project with a DataBinding to the ItemSource.
A MessageConverter creates either TextMessages or GifMessages. This all works fine.
The problem I have is that I want to add a TimeBreak to the top of the list, as I use the chat to store messages in my interface to view later, like a log. The first message can be in the past. And I want to know when this was.
My current solution is to always add one dummy message to the top of the pile, which has a DateTime: 2000-01-01
I've added a Style to my App.Xaml:
<Style BasedOn="{StaticResource InlineMessageControlStyle}" TargetType="conversationalUi:InlineMessageControl">
<EventSetter Event="Loaded" Handler="InlineMessageControl_OnLoaded" />
</Style>
This gives access to the loading of the InlineMessageControl. In which I look up the Message with the CreateAt of 2000-01-01. Like this:
private void InlineMessageControl_OnLoaded(object sender, RoutedEventArgs e)
{
try
{
if (sender is not InlineMessageControl inlineMessageControl) { return; }
//Hide first item, that is inserted manually to force a TimeBreak on the second
if (inlineMessageControl.DataContext is InlineViewModel { CreationDate.Year: 2000 })
{
if (inlineMessageControl.TryFindParent<MessageGroup>() is { } messageGroup)
{
messageGroup.Visibility = Visibility.Collapsed;
}
if (inlineMessageControl.TryFindParent<VirtualizingStackPanel>() is { } panel)
{
panel.Margin = new Thickness(0, -15, 0, 0);
}
}
}
The result can be seen in the PNG attachment. However, I think this method should not be necesarry, as the tool itself should be able to do this using a bool like: AddTimeBreakToTop or something.
I am aware that you can add the Messages manually, but this seems like a even worse solution.
Waht are you thoughts, Am I missing something? Can this be improved?
Second question would be. How do I style the background of the TextMessages?
Hello,
I have an application where I store and add messages from the database. On startup I manually ladd the last so much messages from the database.
When I initially load, all messages and TimeBreaks are displayed fine. However the last message is not in view. The Chat shows the first lines and the scroll bar is positioned at the top, not at the bottom.
When I add new messages via the inputline, the message is in view
I use Telereik 2024.3.821.462
These message are added using the followin code:
View (code behind) => SendMessage event
private void RadChat_SendMessage(object sender, SendMessageEventArgs e)
{
e.Handled = true;
var updatedMessageText = (e.Message as TextMessage).Text;
ViewModel.AddMessage(updatedMessageText);
}
ViewModel => AddMessages
public async void AddMessage(string updatedMessageText)
{
Message newMessage = new Message();
newMessage.Author = CurrentAuthor.Name;
newMessage.MessageDate = DateTime.Now;
newMessage.MessageText = updatedMessageText;
newMaxMessageId = _dashboardDao.InsertMessages(newMessage);
ReadMessages();
}
private async void ReadMessages()
{
IsReloading = true;
newMaxMessageId = _dashboardDao.GetMaxMessageID();
if (newMaxMessageId > currentMaxMessageId)
{
IEnumerable<Message> newMessages = await _dashboardDao.GetNewMessages(currentMaxMessageId, _sharedVM.NumMessageBoardMessages);
newMessages = newMessages.OrderBy(x => x.MessageId).ToList();
if (newMessages.Count() > 0)
{
if (!IsActive)
{
if (_ShowNewMessages)
{
numNewMessages += newMessages.Count();
HasMessagesData hasMessagesData = new HasMessagesData(true, numNewMessages);
_sharedVM.HasMessages = hasMessagesData;
}
else
{
numNewMessages = 0;
}
}
else
{
numNewMessages= 0;
}
NewTextMessages = new ObservableCollection<TextMessageModel>();
newMessages = newMessages.Where(x => x.MessageId > currentMaxMessageId);
NewTextMessages.Clear();
foreach (Message message in newMessages)
{
if (message.Author == CurrentUser)
{
NewTextMessages.Add(new TextMessageModel() { Text = message.MessageText, Author = CurrentAuthor, CreationDate = message.MessageDate });
}
else
{
NewTextMessages.Add(new TextMessageModel() { Text = message.MessageText, Author = new Author(message.Author), CreationDate = message.MessageDate });
}
if (_ShowNewMessages)
{
_eventAggregator.GetEvent<NewMessageShownEvent>().Publish();
}
}
currentMaxMessageId = newMessages.Last().MessageId;
OnPropertyChanged(nameof(NewTextMessages));
}
}
_ShowNewMessages = true;
IsReloading = false;
}
View (code behind) triggerd by OnPropertyChanged(nameof(NewTextMessages))
his.ViewModel.PropertyChanged += (sender, args) =>
{
if (args.PropertyName == "NewTextMessages")
{
AddNewMessages();
}
};
private void AddNewMessages()
{
foreach (var newMessage in ViewModel.NewTextMessages)
{
if (chat.LastMessage == null)
{
this.chat.AddTimeBreak(newMessage.CreationDate.DayOfWeek.ToString() + " " + newMessage.CreationDate.ToString("MMMM") + " " + newMessage.CreationDate.Day.ToString() + ", " + newMessage.CreationDate.Year);
}
else
{
if ((chat.LastMessage.CreationDate.Year != newMessage.CreationDate.Year) || (chat.LastMessage.CreationDate.Month!= newMessage.CreationDate.Month) || (chat.LastMessage.CreationDate.Day != newMessage.CreationDate.Day))
{
this.chat.AddTimeBreak(newMessage.CreationDate.DayOfWeek.ToString() + " " + newMessage.CreationDate.ToString("MMMM") + " " + newMessage.CreationDate.Day.ToString() + ", " + newMessage.CreationDate.Year);
}
}
var textMessage = new TextMessage(newMessage.Author, newMessage.Text, "sent", newMessage.CreationDate);
this.chat.AddMessage(textMessage);
}
}
Hello,
I would like to remove all messages of radchat after inactivity.
I don't find how to remove all messages. Could you help me ?
Thanks
Thomas
Hi,
Im using conversationalUI in a WPF app and would like to update the message in realtime as my openAI response is streaming in to make the UX a better experience on long responses. This should update the message being displayed in realtime as the service is streaming in text.
I only see the ability to do a message.Add() option, I feel like there should also be a AddAsync() method. Is this even possible in this control?
Thanks in advance!
I am creating a little chat demo, by having two chat boxes next to each other (they communicate to each other). My issue is, when I load older messages from the database, I could not properly set a different "current author" for each chat box while maintaining MVVM structure (what I need is: in chatbox 1 user1 is the currentAuthor, in chatbox 2 user 2 is the currnetAuthor)
I am following an MVVM pattern. Code snippets are provided below (I tried to remove all lines irrelevant to the question):
1- my chat boxes
<telerik:RadChat x:Name="chat1"
Width="400"
Height="550"
DataSource="{Binding Chat1Messages}"
CurrentAuthor="{Binding Chat1CurrentAuthor}">
</telerik:RadChat>
<telerik:RadChat x:Name="chat2"
Width="400"
Height="550"
DataSource="{Binding Chat2Messages}"
CurrentAuthor="{Binding Chat2CurrentAuthor}">
</telerik:RadChat>
2- My code in adding the messages from DB:
//some code to get data from DB//
this.chat1CurrentAuthor = this.FirstAuthor;
this.chat2CurrentAuthor = this.SecondAuthor;
//Iterator over data from DB
{
//if message is written by first author:
{
this.Chat1Messages.Add(new TextMessageObject() { Text = row.MessageText, MsgAuthor = this.FirstAuthor, CreationDate = row.Time });
this.Chat2Messages.Add(new TextMessageObject() { Text = row.MessageText, MsgAuthor = this.FirstAuthor, CreationDate = row.Time });
}
//if message is written by second author:
{
this.Chat1Messages.Add(new TextMessageObject() { Text = row.MessageText, MsgAuthor = this.SecondAuthor, CreationDate = row.Time });
this.Chat2Messages.Add(new TextMessageObject() { Text = row.MessageText, MsgAuthor = this.SecondAuthor, CreationDate = row.Time });
}
}
3- code to support MVVM:
public Author Chat1CurrentAuthor
{
get { return this.chat1CurrentAuthor; }
set
{
if (value != this.chat1CurrentAuthor)
{
this.chat1CurrentAuthor = value;
OnPropertyChanged(() => this.chat1CurrentAuthor);
}
}
}
public Author Chat2CurrentAuthor
{
get { return this.chat2CurrentAuthor; }
set
{
if (value != this.chat2CurrentAuthor)
{
this.chat2CurrentAuthor = value;
OnPropertyChanged(() => this.chat2CurrentAuthor);
}
}
}
With my current code, both authors are set up as current authors in both chatboxes (i.e in chatbox1, currentAuthor is both user1 and user2, in chatbox2 currentAuthor is both user1 and user2) which is not the desired behavior.
Hello!
https://www.telerik.com/forums/radchat-messages-not-updated-when-datasource-changed
https://www.telerik.com/forums/update-chat-messages-on-datasource-change
https://feedback.telerik.com/wpf/1357293-chat-setting-a-new-instance-for-the-datasource-does-not-clear-the-previous-messages
In last link:
"*** The fix for this issue will be available with the next LIB (version 2018.3.1210) expected on Monday, December 10."
Where i can find this build?
PS: we use 2018 and do NOT want to migrate to 2019.
Dear Team,
I am facing issue with Chat Control. When I tried to change datasource of control, Messages in Chat UI does not reflect.
I have List of User in listbox. Each User has Observable collection of TextMessages. When User selection changed, I bind datasource to selected user messages. I assume that Chat control will update its UI by selected User messaged. But it is not working.
I tried to clear MessageListItems on selection change, and re-bind datasource to selected user's messages. In this case Chat UI does not show any messages.
For reference I have uploaded my sample project on Google drive.
@Admin: I had already shared the same issue few days ago, but i did not receive any solution.