Reputation: 1505
currently I'm working on a chat client and changed my client from windows forms (as forms is shitty) to WPF. I'm not really sure which control could be used to realize a chatbox. I could take a TextBox but this will not display the complete content when it's full. I also tried to use a ListBox but when I try to add items they are not displayed. I used this code to add content to it:
internal void AddMessage(string message)
{
listBox_messages.Items.Add(message);
listBox_messages.Items.Refresh();
}
Does anybody knows which control would be the best for this purpose?
Thanks for your help!
Edit: I implemented a TextBox for this and disabled it. But the text I'm appending by this method is not shown. My class:
using System.ComponentModel;
using System.Windows;
namespace Chat_Client
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// MainWindow constructor
/// </summary>
public MainWindow()
{
InitializeComponent();
textBox_messages.AppendText("Test" + "\n");
textBox_messages.AppendText("Test" + "\n");
textBox_messages.AppendText("Test" + "\n");
Closing += OnWindowClosing;
}
private void OnWindowClosing(object sender, CancelEventArgs e)
{
Program.Shutdown();
}
private void button_connect_Click(object sender, RoutedEventArgs e)
{
if(Program.Connected)
{
Program.Disconnect();
}
else
{
Program.Connect();
}
}
private void button_sendMessage_Click(object sender, RoutedEventArgs e)
{
}
internal void AddMessage(string message)
{
textBox_messages.AppendText(message + "\n");
}
}
}
The test strings are shown but the text added by the method AddMessage is not. I can verify that the method is called, I just checked it with a breakpoint inside this method. Anybody has a clue how this could happen?
Upvotes: 0
Views: 4095
Reputation: 939
*In response to your edit: where are you calling AddMessage() from? I tried your code and just called AddMessage("foo"); from the button click event and worked fine.
For a chat box, I would use a TextBox to write the chat messages, and wrap it with a ScrollViewer for scrolling. After using AppendText() on the TextBox to write the message, you can then call ScrollToEnd() to scroll to the bottom of the TextBox.
In the XAML:
<ScrollViewer x:Name="ScrollViewer" ScrollChanged="ScrollViewer_OnScrollChanged">
<TextBox x:Name="ChatBox"/>
</ScrollViewer>
In the code behind:
private void WriteToChat(string message)
{
ChatBox.AppendText(message);
ChatBox.ScrollToEnd();
}
private bool _autoScroll = true;
private void ScrollViewer_OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.ExtentHeightChange == 0)
{
_autoScroll = ScrollViewer.VerticalOffset == ScrollViewer.ScrollableHeight;
}
if (_autoScroll && e.ExtentHeightChange != 0)
{
ScrollViewer.ScrollToVerticalOffset(ScrollViewer.ExtentHeight);
}
}
Upvotes: 2
Reputation: 180
Update
If the Program class calls AddMessage(string) from within another thread than the UI thread, you have to use a Dispatcher in order to update the UI.
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
mainWindow.AddMessage(message);
}));
MVVM is the way to go when using WPF.
public class ChatViewModel
{
public ObservableCollection<string> Messages { get; } = new ObservableCollection<string>();
internal void AddMessage(string message)
{
Messages.Add(message);
}
}
public ChatView : UserControl
{
public ChatView()
{
InitializeComponent();
DataContext = new ChatViewModel();
}
}
<ListBox ItemsSource="{Binding Messages}") />
When you add a message to the Messages collection it should appear inside the ListBox. This is not a complete example, but it should guide you into the right direction.
Upvotes: 3
Reputation: 84
You can use a TextBox and set the VerticalAlignment to Stretch in your Xaml file.
< TextBox x:Name="textbox" VerticalAlignment="Stretch">
Upvotes: 0