Edit or Delete a message using RadContextMenu
Product Version | Product | Author |
---|---|---|
2022.1.222 | RadChatView for WinForms | Dinko Krastev |
Problem
At this time of writing this KB article, the RadChat control does not provide an API to edit/delete its messages through a RadContextMenu.
Solution
The control is very customizable and you could achieve this scenario using custom code.
- First we need to create RadContextMenu with two RadMenuItems (Edit/Delete) and subscribe to their Click events. In their event handler, we can execute our custom logic.
- In the ItemFormatting event of the RadChat we can get an instance of each message and subscribe to its MouseDown event. In its event handler, we can show the menu.
- Editing a message will require adding additional RadTextBox placed in RadHostItem which we will use for the editing process. When the user clicks on the Edit RadMenuItem, we can show the RadTextBox. The user will enter the new message and pressing enter, for example, will change the actual message.
- Deleting a message is much easier. When the user clicks on the Delete RadMenuItem, we can get the current clicked message and delete it from the RadChat.ChatElement.MessagesViewElement.Items collection.
- This approach can be further customized to mark the edited text and perform some other custom logic depending on the edited text.
- Full sample code can be found below.
public partial class RadForm1 : System.Windows.Forms.Form
{
RadContextMenu contextMenu = new RadContextMenu();
RadTextBox textBox;
RadHostItem hostItem;
TextMessageItemElement currentClickedTextMessageItemElement;
private Author author2;
public RadForm1()
{
InitializeComponent();
new RadControlSpyForm().Show();
this.radChat1.AutoAddUserMessages = true;
this.radChat1.SendMessage += radChat1_SendMessage;
this.radChat1.Author = new Author(Properties.Resources.Janet, "User");
author2 = new Author(Properties.Resources.AndrewFuller, "devNXT Bot");
RadMenuItem editItem = new RadMenuItem("Edit");
editItem.Click += EditItem_Click;
RadMenuItem deleteItem = new RadMenuItem("Delete");
deleteItem.Click += DeleteItem_Click;
contextMenu.Items.Add(editItem);
contextMenu.Items.Add(deleteItem);
this.radChat1.ItemFormatting += RadChat1_ItemFormatting1;
}
private void RadChat1_ItemFormatting1(object sender, ChatItemElementEventArgs e)
{
LightVisualElement bubble = e.ItemElement.MainMessageElement;
if (e.ItemElement is TextMessageItemElement )
{
bubble.MouseDown -= RadForm1_MouseDown;
bubble.MouseDown += RadForm1_MouseDown;
bool isUpdated = (e.ItemElement as TextMessageItemElement).Tag != null ? true : false;
if(isUpdated)
{
bubble.DrawFill = true;
bubble.BackColor = Color.LightGreen;
}
}
else
{
bubble.ResetValue(LightVisualElement.DrawBorderProperty, Telerik.WinControls.ValueResetFlags.Local);
bubble.ResetValue(LightVisualElement.BackColorProperty, Telerik.WinControls.ValueResetFlags.Local);
}
}
private void DeleteItem_Click(object sender, EventArgs e)
{
var menuItem = sender as MenuItem;
this.radChat1.ChatElement.MessagesViewElement.Items.Remove(currentClickedTextMessageItemElement.Data);
}
private void EditItem_Click(object sender, EventArgs e)
{
if (currentClickedTextMessageItemElement.Data.Message is ChatTextMessage)
{
if (textBox == null)
{
textBox = new RadTextBox();
textBox.KeyDown += T_KeyDown;
hostItem = new RadHostItem(textBox);
hostItem.MinSize = new Size(200, 24);
}
currentClickedTextMessageItemElement.MainMessageElement.DrawText = false;
currentClickedTextMessageItemElement.MainMessageElement.Children.Add(hostItem);
textBox.Text = (currentClickedTextMessageItemElement.Data.Message as ChatTextMessage).Message;
}
}
private void T_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Return)
{
var ctm = currentClickedTextMessageItemElement.Data.Message as ChatTextMessage;
ctm.Message = textBox.Text;
// Submit
currentClickedTextMessageItemElement.MainMessageElement.Children.Remove(hostItem);
currentClickedTextMessageItemElement.Tag = "Updated";
VirtualAssistanChat(ctm.Message);
}
else if (e.KeyData == Keys.Escape)
{
// Cancel
// Remove editor
currentClickedTextMessageItemElement.MainMessageElement.Children.Remove(hostItem);
}
currentClickedTextMessageItemElement.MainMessageElement.DrawText = true;
}
private void RadForm1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
currentClickedTextMessageItemElement = (sender as ChatMessageBubbleElement).Parent as TextMessageItemElement;
contextMenu.Show(this, new Point(e.X, e.Y));
}
}
private void radChat1_SendMessage(object sender, SendMessageEventArgs e)
{
Telerik.WinControls.UI.ChatTextMessage chatMessage = (Telerik.WinControls.UI.ChatTextMessage)e.Message;
this.radChat1.AutoAddUserMessages = true;
VirtualAssistanChat(chatMessage.Message);
}
private void radChat1_SuggestedActionClicked(object sender, SuggestedActionEventArgs e)
{
this.radChat1.AddMessage(new ChatTextMessage("You have chosen " + e.Action.Text, this.radChat1.Author, DateTime.Now));
}
void VirtualAssistanChat(string message)
{
if (message == "Hello")
{
ChatTextMessage message12 = new ChatTextMessage("I am your Virtual Assistant", author2, DateTime.Now.AddSeconds(15));
this.radChat1.AddMessage(message12);
}
if (message.Contains("Options"))
{
ChatTextMessage message12 = new ChatTextMessage("Below are your Automation options:", author2, DateTime.Now.AddSeconds(15));
this.radChat1.AddMessage(message12);
List<SuggestedActionDataItem> suggestedActions = new List<SuggestedActionDataItem>();
suggestedActions.Add(new SuggestedActionDataItem(".Net Core Conversion"));
suggestedActions.Add(new SuggestedActionDataItem("Code Forensics"));
this.radChat1.AddMessage(new ChatSuggestedActionsMessage(suggestedActions, author2, DateTime.Now));
ChatSuggestedActionsMessage suggestionActionsMessage = new ChatSuggestedActionsMessage(suggestedActions, author2, DateTime.Now);
this.radChat1.AddMessage(suggestionActionsMessage);
this.radChat1.SuggestedActionClicked -= radChat1_SuggestedActionClicked;
this.radChat1.SuggestedActionClicked += radChat1_SuggestedActionClicked;
}
if (message.Contains(".Net Core Conversion"))
{
ChatTextMessage message12 = new ChatTextMessage("Below are your Conversion options:", author2, DateTime.Now.AddSeconds(5));
this.radChat1.AddMessage(message12);
List<SuggestedActionDataItem> actions = new List<SuggestedActionDataItem>();
actions.Add(new SuggestedActionDataItem("Console Application"));
actions.Add(new SuggestedActionDataItem("MVC"));
actions.Add(new SuggestedActionDataItem("Windows App"));
actions.Add(new SuggestedActionDataItem("Restful"));
actions.Add(new SuggestedActionDataItem("SOAP"));
actions.Add(new SuggestedActionDataItem("Container"));
actions.Add(new SuggestedActionDataItem("Others"));
this.radChat1.AddMessage(new ChatSuggestedActionsMessage(actions, author2, DateTime.Now));
ChatSuggestedActionsMessage suggestionActionsMessage = new ChatSuggestedActionsMessage(actions, author2, DateTime.Now);
this.radChat1.AddMessage(suggestionActionsMessage);
this.radChat1.SuggestedActionClicked -= radChat1_SuggestedActionClicked;
this.radChat1.SuggestedActionClicked += radChat1_SuggestedActionClicked;
}
}
}
Partial Public Class RadForm2
Inherits System.Windows.Forms.Form
Private contextMenu As RadContextMenu = New RadContextMenu()
Private textBox As RadTextBox
Private hostItem As RadHostItem
Private currentClickedTextMessageItemElement As TextMessageItemElement
Private author2 As Author
Public Sub New()
InitializeComponent()
Me.RadChat1.AutoAddUserMessages = True
AddHandler Me.RadChat1.SendMessage, AddressOf radChat1_SendMessage
Me.RadChat1.Author = New Author(My.Resources.Janet, "User")
author2 = New Author(My.Resources.AndrewFuller, "devNXT Bot")
Dim editItem As RadMenuItem = New RadMenuItem("Edit")
AddHandler editItem.Click, AddressOf EditItem_Click
Dim deleteItem As RadMenuItem = New RadMenuItem("Delete")
AddHandler deleteItem.Click, AddressOf DeleteItem_Click
contextMenu.Items.Add(editItem)
contextMenu.Items.Add(deleteItem)
AddHandler Me.radChat1.ItemFormatting, AddressOf RadChat1_ItemFormatting1
End Sub
Private Sub RadChat1_ItemFormatting1(ByVal sender As Object, ByVal e As ChatItemElementEventArgs)
Dim bubble As LightVisualElement = e.ItemElement.MainMessageElement
If TypeOf e.ItemElement Is TextMessageItemElement Then
RemoveHandler bubble.MouseDown, AddressOf RadForm1_MouseDown
AddHandler bubble.MouseDown, AddressOf RadForm1_MouseDown
Dim isUpdated As Boolean = If((TryCast(e.ItemElement, TextMessageItemElement)).Tag IsNot Nothing, True, False)
If isUpdated Then
bubble.DrawFill = True
bubble.BackColor = Color.LightGreen
End If
Else
bubble.ResetValue(LightVisualElement.DrawBorderProperty, Telerik.WinControls.ValueResetFlags.Local)
bubble.ResetValue(LightVisualElement.BackColorProperty, Telerik.WinControls.ValueResetFlags.Local)
End If
End Sub
Private Sub DeleteItem_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim menuItem = TryCast(sender, MenuItem)
Me.radChat1.ChatElement.MessagesViewElement.Items.Remove(currentClickedTextMessageItemElement.Data)
End Sub
Private Sub EditItem_Click(ByVal sender As Object, ByVal e As EventArgs)
If TypeOf currentClickedTextMessageItemElement.Data.Message Is ChatTextMessage Then
If textBox Is Nothing Then
textBox = New RadTextBox()
AddHandler textBox.KeyDown, AddressOf T_KeyDown
hostItem = New RadHostItem(textBox)
hostItem.MinSize = New Size(200, 24)
End If
currentClickedTextMessageItemElement.MainMessageElement.DrawText = False
currentClickedTextMessageItemElement.MainMessageElement.Children.Add(hostItem)
textBox.Text = (TryCast(currentClickedTextMessageItemElement.Data.Message, ChatTextMessage)).Message
End If
End Sub
Private Sub T_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.KeyData = Keys.[Return] Then
Dim ctm = TryCast(currentClickedTextMessageItemElement.Data.Message, ChatTextMessage)
ctm.Message = textBox.Text
currentClickedTextMessageItemElement.MainMessageElement.Children.Remove(hostItem)
currentClickedTextMessageItemElement.Tag = "Updated"
VirtualAssistanChat(ctm.Message)
ElseIf e.KeyData = Keys.Escape Then
currentClickedTextMessageItemElement.MainMessageElement.Children.Remove(hostItem)
End If
currentClickedTextMessageItemElement.MainMessageElement.DrawText = True
End Sub
Private Sub RadForm1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Right Then
currentClickedTextMessageItemElement = TryCast((TryCast(sender, ChatMessageBubbleElement)).Parent, TextMessageItemElement)
contextMenu.Show(Me, New Point(e.X, e.Y))
End If
End Sub
Private Sub radChat1_SendMessage(ByVal sender As Object, ByVal e As SendMessageEventArgs)
Dim chatMessage As Telerik.WinControls.UI.ChatTextMessage = CType(e.Message, Telerik.WinControls.UI.ChatTextMessage)
Me.radChat1.AutoAddUserMessages = True
VirtualAssistanChat(chatMessage.Message)
End Sub
Private Sub radChat1_SuggestedActionClicked(ByVal sender As Object, ByVal e As SuggestedActionEventArgs)
Me.radChat1.AddMessage(New ChatTextMessage("You have chosen " & e.Action.Text, Me.radChat1.Author, DateTime.Now))
End Sub
Private Sub VirtualAssistanChat(ByVal message As String)
If message = "Hello" Then
Dim message12 As ChatTextMessage = New ChatTextMessage("I am your Virtual Assistant", author2, DateTime.Now.AddSeconds(15))
Me.radChat1.AddMessage(message12)
End If
If message.Contains("Options") Then
Dim message12 As ChatTextMessage = New ChatTextMessage("Below are your Automation options:", author2, DateTime.Now.AddSeconds(15))
Me.radChat1.AddMessage(message12)
Dim suggestedActions As List(Of SuggestedActionDataItem) = New List(Of SuggestedActionDataItem)()
suggestedActions.Add(New SuggestedActionDataItem(".Net Core Conversion"))
suggestedActions.Add(New SuggestedActionDataItem("Code Forensics"))
Me.radChat1.AddMessage(New ChatSuggestedActionsMessage(suggestedActions, author2, DateTime.Now))
Dim suggestionActionsMessage As ChatSuggestedActionsMessage = New ChatSuggestedActionsMessage(suggestedActions, author2, DateTime.Now)
Me.RadChat1.AddMessage(suggestionActionsMessage)
RemoveHandler Me.RadChat1.SuggestedActionClicked, AddressOf radChat1_SuggestedActionClicked
AddHandler Me.RadChat1.SuggestedActionClicked, AddressOf radChat1_SuggestedActionClicked
End If
If message.Contains(".Net Core Conversion") Then
Dim message12 As ChatTextMessage = New ChatTextMessage("Below are your Conversion options:", author2, DateTime.Now.AddSeconds(5))
Me.radChat1.AddMessage(message12)
Dim actions As List(Of SuggestedActionDataItem) = New List(Of SuggestedActionDataItem)()
actions.Add(New SuggestedActionDataItem("Console Application"))
actions.Add(New SuggestedActionDataItem("MVC"))
actions.Add(New SuggestedActionDataItem("Windows App"))
actions.Add(New SuggestedActionDataItem("Restful"))
actions.Add(New SuggestedActionDataItem("SOAP"))
actions.Add(New SuggestedActionDataItem("Container"))
actions.Add(New SuggestedActionDataItem("Others"))
Me.radChat1.AddMessage(New ChatSuggestedActionsMessage(actions, author2, DateTime.Now))
Dim suggestionActionsMessage As ChatSuggestedActionsMessage = New ChatSuggestedActionsMessage(actions, author2, DateTime.Now)
Me.radChat1.AddMessage(suggestionActionsMessage)
RemoveHandler Me.RadChat1.SuggestedActionClicked, AddressOf radChat1_SuggestedActionClicked
AddHandler Me.RadChat1.SuggestedActionClicked, AddressOf radChat1_SuggestedActionClicked
End If
End Sub
End Class