WPF Binding Custom Output Window
data-binding, textbox, wpf, xaml
Solution
I think what Thomas was saying is that you could have the following in your Window's codebehind:
public partial class MyWindow : Window
{
ViewModel _vm;
public MyWindow(ViewModel vm)
{
InitializeComponent();
_vm = vm;
_vm.Output.CollectionChanged += Output_CollectionChanged;
}
void Output_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach(object item in e.NewItems)
{
outputTextBox.AppendText(item.ToString());
}
}
}
This way, the window class will automatically append any text that is added to the Output collection.
Another way to do it (though it may not be considered pure MVVM) is by using an interface as follows:
public interface IAppendOutput
{
void Append(string text);
}
public partial class MyWindow : Window, IAppendOutput
{
public MyWindow()
{
InitializeComponent();
}
public void Append(string text)
{
outputTextBox.AppendText(text);
}
}
public class ViewModel
{
IAppendOutput _outputter;
public ViewModel(IAppendOutput outputter)
{
_outputter = outputter;
}
public void AppendOutput(string text)
{
_outputter.Append(text);
}
}
Then in your main app:
...
MyWindow window = new MyWindow();
ViewModel vm = new ViewModel(window);
window.DataContext = vm;
window.Show();
vm.AppendOutput("This is a test.");
...
This way may not be the best way of doing it, but it may be a useful method for writing quick duct-tape code for other circumstances. It is still unit-testable because the ViewModel has no knowledge of the window itself, only an interface. It is still flexible because you can customize any sort of object so that it implements the IAppendOutput interface.
Problem
I am trying to create a custom Output Window for my software that is bound to my ViewModel. Usually in the past I have always used a TextBox and used the `appendText()` method to write to the Output Window. Of course with a ViewModel and trying to bind to a Textbox, it seems you can only Bind to the `Text` property. Below is what I am trying to do: XAML: ``` <TextBox Text="{Binding Output}"></TextBox> ``` C# ``` public class ViewModel : DependencyObject { public static readonly DependencyProperty OutputProperty = DependencyProperty.Register("Output", typeof(ObservableCollection<string>), typeof(MVVMTestViewModel), new UIPropertyMetadata(null)); public ObservableCollection<string> Output { get { return (ObservableCollection<string>)GetValue(OutputProperty); } set { SetValue(OutputProperty, value); } } public ViewModel() { Output = new ObservableCollection<string>(); } public void OutputMessage(string message) { Output.Add(message); } } ``` Of course this is not possible because Text cannot be assigned to an Observable Collection. Note: I could use a ListView, or a ListBox and use an observable collection. But I do not like the selection mode. I like to be able to highlight the text of a TextBox so that I can copy and paste it out of the Window. The `isReadOnly` property allows me to do this fairly easily. Is there an easy way to do this? Another Control I haven't though of perhaps?